Go Back   EQEmulator Home > EQEmulator Forums > Archives > Archive::Development > Archive::Quests

Archive::Quests Archive area for Quests's posts that were moved here after an inactivity period of 90 days.

Reply
 
Thread Tools Display Modes
  #31  
Old 08-08-2004, 03:52 PM
killspree
Dragon
 
Join Date: Jun 2002
Posts: 776
Default

I've come up with a "fix" for the problem of quest items sticking with an npc - it's a temp fix for now until I have more time to take a look at options to the "npc's can equip items" code. Basically what I did was add a new field to the npc_types index in the database called "questflag". I then added a function to check it and put it within the Client::FinishTrade function. It checks the questflag field in npc_types, and if 0 is returned, it allows the npc to have the item added to its loot table. If 1 is returned, the item is ignored(for loot table purposes - the npc still accepts the item through all tests I've done).

In client.cpp, replace Client::FinishTrade() with:
Code:
void Client::FinishTrade(NPC* with){
	int32 items[4]={0};
	int8 charges[4]={0};
	for (sint16 i=3000; i<=3003; i++){
		const ItemInst* inst = m_inv[i];
		if (inst) {
			items[i-3000]=inst->GetItem()->ItemNumber;
			charges[i-3000]=inst->GetCharges();
			DeleteItemInInventory(i);
		}
	}
	char temp1[100];
	memset(temp1,0x0,100);
	char temp2[100];
	memset(temp2,0x0,100);
	for ( int z=0; z < 4; z++ ) {
		sprintf(temp1,"item%d.%d", z+1,with->GetNPCTypeID());
		sprintf(temp2,"%d",items[z]);
		parse->AddVar(temp1,temp2);
		memset(temp1,0x0,100);
		memset(temp2,0x0,100);
	}
	sprintf(temp1,"copper.%d",with->GetNPCTypeID());
	sprintf(temp2,"%i",trade->cp);
	parse->AddVar(temp1,temp2);
	memset(temp1,0x0,100);
	memset(temp2,0x0,100);
	sprintf(temp1,"silver.%d",with->GetNPCTypeID());
	sprintf(temp2,"%i",trade->sp);
	parse->AddVar(temp1,temp2);
	memset(temp1,0x0,100);
	memset(temp2,0x0,100);
	sprintf(temp1,"gold.%d",with->GetNPCTypeID());
	sprintf(temp2,"%i",trade->gp);
	parse->AddVar(temp1,temp2);
	memset(temp1,0x0,100);
	memset(temp2,0x0,100);
	sprintf(temp1,"platinum.%d",with->GetNPCTypeID());
	sprintf(temp2,"%i",trade->pp);
	parse->AddVar(temp1,temp2);
	memset(temp1,0x0,100);
	memset(temp2,0x0,100);
	parse->Event(EVENT_ITEM, with->GetNPCTypeID(), 0, with, this->CastToMob());
	LinkedListIterator<ServerLootItem_Struct*> iterator(*with->CastToNPC()->itemlist);
	iterator.Reset();
	int xy = 0;
	while(iterator.MoreElements()) {
		xy++;
		iterator.Advance();
	}
	
	for(int y=0;y<4;y++){
		if (xy <20){
			xy++;
			NPC* npc=with->CastToNPC();
			const Item_Struct* item2 = database.GetItem(items[y]);
			if (item2) { //no "no drop" items for j00!
				ServerLootItem_Struct* item = new ServerLootItem_Struct;
				item->item_id = item2->ItemNumber;
				item->charges = charges[y];
				char newid[20];
				memset(newid, 0, sizeof(newid));
				for(int i=0;i<7;i++){
					if (!isalpha(item2->IDFile[i])){
						strncpy(newid, &item2->IDFile[i],5);
						i=8;
					}
				}
				APPLAYER* outapp = new APPLAYER(OP_WearChange, sizeof(WearChange_Struct));
	 			WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer;
	 			wc->spawn_id = npc->GetID();
				wc->material=0;
				if (((item2->EquipSlots==24576) || (item2->EquipSlots==8192)) && (npc->d_meele_texture1==0)) {
					wc->wear_slot_id=7;
					if (item2->Common.SpellId!=0)
						npc->CastToMob()->AddProcToWeapon(item2->Common.SpellId,true);
					npc->equipment[7]=item2->ItemNumber;
					npc->d_meele_texture1=atoi(newid);
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}
				else if (((item2->EquipSlots==24576) || (item2->EquipSlots==16384)) && (npc->d_meele_texture2 ==0) && ((npc->GetLevel()>=13) || (item2->Common.Damage==0))) 
				{
					if (item2->Common.SpellId!=0)
						npc->CastToMob()->AddProcToWeapon(item2->Common.SpellId,true);
					npc->d_meele_texture2=atoi(newid);
					npc->equipment[8]=item2->ItemNumber;
					wc->wear_slot_id=8;
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}
				else if ((item2->EquipSlots==4) && (npc->equipment[0]==0)){

					npc->equipment[0]=atoi(newid);
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					wc->wear_slot_id=0;
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}
				else if ((item2->EquipSlots==131072) && (npc->equipment[1]==0)){
					npc->equipment[1]=atoi(newid);
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					wc->wear_slot_id=1;
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}
				else if ((item2->EquipSlots==128) && (npc->equipment[2]==0)){
					npc->equipment[2]=atoi(newid);
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					wc->wear_slot_id=2;
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;

					npc->INT+=item2->Common.INT;
				}
				else if ((item2->EquipSlots==1536) && (npc->equipment[3]==0)){
					npc->equipment[3]=atoi(newid);
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					wc->wear_slot_id=3;
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}

				else if ((item2->EquipSlots==4096) && (npc->equipment[4]==0)){
					npc->equipment[4]=atoi(newid);
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					wc->wear_slot_id=4;
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}
				else if ((item2->EquipSlots==262144) && (npc->equipment[5]==0)){
					npc->equipment[5]=atoi(newid);
					if (item2->Common.Material >0)

						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					wc->wear_slot_id=5;
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}
				else if ((item2->EquipSlots==524288) && (npc->equipment[6]==0)){
					npc->equipment[6]=atoi(newid);
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					wc->wear_slot_id=6;
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;


					npc->INT+=item2->Common.INT;
				}
				if (((npc->GetRace()==127) && (npc->CastToMob()->GetOwnerID()!=0)) && (item2->EquipSlots==24576) || (item2->EquipSlots==8192) || (item2->EquipSlots==16384)){
					npc->d_meele_texture2=atoi(newid);
					wc->wear_slot_id=8;
					if (item2->Common.Material >0)
						wc->material=item2->Common.Material;
					else
						wc->material=atoi(newid);
					npc->AC+=item2->Common.AC;
					npc->STR+=item2->Common.STR;
					npc->INT+=item2->Common.INT;
				}
				item->equipSlot = item2->EquipSlots;
				if((item2->NoDrop != 0 && !parse->HasQuestFile(with->GetNPCTypeID())) || this->GetGM())
	            if(GetQuestNPCFlag(CastToClient()->GetTarget()->CastToNPC()->GetNPCTypeID()) == 0){//Killspree: QuestNPC check
		        (*npc->itemlist).Append(item);//npc isn't a quest npc, let it have the item
	 			entity_list.QueueClients(this, outapp);
	 			safe_delete(outapp);
				}
	            else{
	 			entity_list.QueueClients(this, outapp);
	 			safe_delete(outapp);
		        //Killspree: This npc is a quest npc, letting it keep items can be bad for duping!
				}
			}
		 }
	 }
 }
Now above/below that add:
Code:
int8 GetQuestNPCFlag(int32 npcid){
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;
    MYSQL_RES *result;
    MYSQL_ROW row;
	if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT questflag FROM npc_types WHERE id=%i",npcid), errbuf, &result)) {
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1)
		{
			row = mysql_fetch_row(result);
			int8 questflag = atoi(row[0]);
			mysql_free_result(result);
			return questflag;
		}
		else
		{
			mysql_free_result(result);
			return 0;
		}
		mysql_free_result(result);
	}
	else
	{
		cerr << "Error in GetQuestNPCFlag query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}
	
	return 0;
}
There you have it. If you have any problems with the code, please let me know and I'll take a look at it. If you have any suggestions on where better to place it by all means speak up on that as well.

For the database portion, simply type the following:
Code:
ALTER TABLE `npc_types` ADD `questflag` TINYINT(4) DEFAULT "0" NOT NULL AFTER `AC`
There you go. You'll have to set the "questflag" field to 1 for any NPCs you don't want to keep items given to them, default is 0.
__________________
Xeldan
Lead Content Designer
Shards of Dalaya
Reply With Quote
  #32  
Old 08-10-2004, 06:06 AM
killspree
Dragon
 
Join Date: Jun 2002
Posts: 776
Default

Anyone tried this yet? Curious if it's working ok.
__________________
Xeldan
Lead Content Designer
Shards of Dalaya
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 02:25 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 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3