Browse Source

some broker display fixes / charge and use fixes

Fix #330 - fix charge and use to correctly decrement in inventory and/or remove item.  Should never call RemoveItem or DeleteItem in LUA use of an Item.

    Items with a charge count (not a physical stack of items) will now count down their charges to 0 and display 'This item is out of charges.'
    Items with an actual stack amount (eg. stack count is larger than 1) will remove an item with each 'use' down to 0 which removes the final item in the stack.
    display_charges is no longer required for the "use" function to be called (before we were decrementing display charges when the "use" function was called, which was always after 1). Now rely on the item->details.count

Fix #328 - broker display issues (some not all)

    tier 0 items do not display
    2h item types do not work
    Max charges when you buy an item with a charge count
    Additional missing items seen on broker: Gust of insight... min_skill and max_skill is a range of 0-6 from client->server, all the way back to classic. Classic UI has it, obselete is 0, 6 goes to unusable (red) for the player. The items skill items to not match this range, they are actual skill values.
    1h item types show both 1h/2h weapons (now 1h and 2h are separated)
Image 3 years ago
parent
commit
e0f8d03773

+ 16 - 5
EQ2/source/WorldServer/Commands/Commands.cpp

@@ -1736,14 +1736,22 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 					if (item->generic_info.max_charges == 0 || item->generic_info.max_charges == 0xFFFF)
 						lua_interface->RunItemScript(item->GetItemScript(), "used", item, player);
 					else {
-						if (item->generic_info.display_charges > 0) {
+						if (item->details.count > 0) {
 							lua_interface->RunItemScript(item->GetItemScript(), "used", item, player);
-							item->generic_info.display_charges -= 1;
-							item->save_needed = true;
-							client->QueuePacket(item->serialize(client->GetVersion(), false, client->GetPlayer()));
+							if(!item->generic_info.display_charges && item->generic_info.max_charges == 1)
+								client->RemoveItem(item, 1); // end of a set of charges OR an item that uses a stack count of actual item quantity
+							else
+							{
+								item->details.count--; // charges
+								item->save_needed = true;
+								client->QueuePacket(item->serialize(client->GetVersion(), false, client->GetPlayer()));
+							}
 						}
 						else
-							LogWrite(PLAYER__ERROR, 0, "Command", "%s: Item %s (%i) attempted to be used, however display_charges is 0.", client->GetPlayer()->GetName(), item->name.c_str(), item->details.item_id);
+						{
+							client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Item is out of charges.");
+							LogWrite(PLAYER__ERROR, 0, "Command", "%s: Item %s (%i) attempted to be used, however details.count is 0.", client->GetPlayer()->GetName(), item->name.c_str(), item->details.item_id);
+						}
 					}
 				}
 			}
@@ -3658,6 +3666,9 @@ void Commands::Process(int32 index, EQ2_16BitString* command_parms, Client* clie
 			if(sep && sep->arg[1][0] && sep->IsNumber(0) && sep->IsNumber(1)){
 				int32 item_id = atoul(sep->arg[0]);
 				int16 quantity = atoul(sep->arg[1]);
+				Item* item = master_item_list.GetItem(item_id);
+				if(item && item->generic_info.max_charges > 1)
+					quantity = item->generic_info.max_charges;
 				client->AddItem(item_id, quantity);
 			}
 			break;

+ 8 - 4
EQ2/source/WorldServer/Items/Items.cpp

@@ -160,7 +160,7 @@ vector<Item*>* MasterItemList::GetItems(string name, int64 itype, int32 ltype, i
 						break;
 					}
 					case ITEM_BROKER_TYPE_CRUSHWEAPON:{
-						if(item->IsCrushWeapon())
+						if(item->IsCrushWeapon() && (item->weapon_info->wield_type == ITEM_WIELD_TYPE_DUAL || item->weapon_info->wield_type == ITEM_WIELD_TYPE_SINGLE))
 							should_add = true;
 						break;
 					}
@@ -200,7 +200,7 @@ vector<Item*>* MasterItemList::GetItems(string name, int64 itype, int32 ltype, i
 						break;
 					}
 					case ITEM_BROKER_TYPE_PIERCEWEAPON:{
-						if(item->IsPierceWeapon())
+						if(item->IsPierceWeapon() && (item->weapon_info->wield_type == ITEM_WIELD_TYPE_DUAL || item->weapon_info->wield_type == ITEM_WIELD_TYPE_SINGLE))
 							should_add = true;
 						break;
 					}
@@ -235,7 +235,7 @@ vector<Item*>* MasterItemList::GetItems(string name, int64 itype, int32 ltype, i
 						break;
 					}
 					case ITEM_BROKER_TYPE_SLASHWEAPON:{
-						if(item->IsSlashWeapon())
+						if(item->IsSlashWeapon() && (item->weapon_info->wield_type == ITEM_WIELD_TYPE_DUAL || item->weapon_info->wield_type == ITEM_WIELD_TYPE_SINGLE))
 							should_add = true;
 						break;
 					}
@@ -619,7 +619,7 @@ vector<Item*>* MasterItemList::GetItems(string name, int64 itype, int32 ltype, i
 						break;
 					}
 					default: {
-						LogWrite(ITEM__ERROR, 0, "Item", "Unknown item broker stat type %u", btype);
+						LogWrite(ITEM__DEBUG, 0, "Item", "Unknown item broker stat type %u", btype);
 						LogWrite(ITEM__DEBUG, 0, "Item", "If you have a client before the new expansion this may be the reason.  Please be patient while we update items to support the new client.", btype);
 						break;
 					}
@@ -653,10 +653,14 @@ vector<Item*>* MasterItemList::GetItems(string name, int64 itype, int32 ltype, i
 				continue;
 			if(maxtier > 0 && item->details.tier > maxtier)
 				continue;
+
+			/* these skill values are not fields provided in the UI beyond CLASSIC
+			** They are also not in line with skill_min, they provide a scale of 0-6, obselete is 0, 6 is red (cannot be used)
 			if(minskill > 0 && item->generic_info.skill_min < minskill)
 				continue;
 			if(maxskill > 0 && item->generic_info.skill_min > maxskill)
 				continue;
+			*/
 			ret->push_back(item);
 		}
 	}

+ 11 - 5
EQ2/source/WorldServer/WorldDatabase.cpp

@@ -2186,9 +2186,10 @@ int32 WorldDatabase::SaveCharacter(PacketStruct* create, int32 loginID){
 	int8 race_id = create->getType_int8_ByName("race");
 	int8 orig_class_id = create->getType_int8_ByName("class");//Normal server
 	int8 class_id = orig_class_id;
-	if ( create->GetVersion() <= 546 )
+	if ( create->GetVersion() <= 546 ) {
 		class_id = 0; //Classic Server Only
-
+	}
+	
 	int8 gender_id = create->getType_int8_ByName("gender");
 	sint16 auto_admin_status = 0;
 
@@ -2212,15 +2213,17 @@ int32 WorldDatabase::SaveCharacter(PacketStruct* create, int32 loginID){
 
 	auto_admin_status = GetHighestCharacterAdminStatus(loginID);
 
-	if( auto_admin_status > 0 && auto_admin_gm )
+	if( auto_admin_status > 0 && auto_admin_gm ) {
 		LogWrite(WORLD__WARNING, 0, "World", "New character '%s' granted GM status (%i) from accountID: %i", create->getType_EQ2_16BitString_ByName("name").data.c_str(), auto_admin_status, loginID);
+	}
 	else if( auto_admin_players )
 	{
 		auto_admin_status = rule_manager.GetGlobalRule(R_World, AutoAdminStatusValue)->GetSInt16();
 		LogWrite(WORLD__DEBUG, 0, "World", "New character '%s' granted AutoAdminPlayer status: %i", create->getType_EQ2_16BitString_ByName("name").data.c_str(), auto_admin_status);
 	}
-	else
+	else {
 		auto_admin_status = 0;
+	}
 
 	string create_char = string("Insert into characters (account_id, server_id, name, race, class, gender, deity, body_size, body_age, soga_wing_type, soga_chest_type, soga_legs_type, soga_hair_type, soga_model_type, legs_type, chest_type, wing_type, hair_type, model_type, facial_hair_type, soga_facial_hair_type, created_date, last_saved, admin_status) values(%i, %i, '%s', %i, %i, %i, %i, %f, %f, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, now(), unix_timestamp(), %i)");
 
@@ -2229,7 +2232,7 @@ int32 WorldDatabase::SaveCharacter(PacketStruct* create, int32 loginID){
 						create->getType_int32_ByName("server_id"), 
 						create->getType_EQ2_16BitString_ByName("name").data.c_str(), 
 						race_id, 
-						orig_class_id,
+						class_id,
 						gender_id, 
 						create->getType_int8_ByName("deity"), 
 						create->getType_float_ByName("body_size"), 
@@ -7683,7 +7686,10 @@ void WorldDatabase::LoadCharacterSpellEffects(int32 char_id, Client* client, int
 			if(target_char_id == 0xFFFFFFFF && player->HasPet())
 				targetID = player->GetPet()->GetID();
 			else if(target_char_id == player->GetCharacterID())
+			{
 				targetID = player->GetID();
+				tmpClient = player->GetClient();
+			}
 			else if((tmpClient = zone_list.GetClientByCharID(target_char_id)) != nullptr && tmpClient->GetPlayer())
 				targetID = tmpClient->GetPlayer()->GetID();