Browse Source

- Fix #542 - DoF will now properly roll/pitch spawns/objects as expected
- Fix #538 - Item quest offer color and part of quest color mapping corrected
- Fix #519 - DoF broker now supports multiple pages, properly displays item name in the field area expected.
- Fix #518 - DoF client mender / repair fixed.
- Negated Control Effect 32 from DoF client, was causing low gravity when safe fall was on a spell.
- Fixed some LUA Functions handling of dead pointers and cleanup of the LUA stack.
- Fixed SpiritShard.lua to convert the timestamp to numerical from string
- Fixed a memory leak on PacketStruct handling of WS_Resurrected
- Fixed being dead allowing you to move around/jump on DoF client
- Fixed DoF control flags when revived/resurrecting to allow movement again
- Fixed reviving not setting HP and leaving player as a corpse (in any client)
- Fixed LUA Function SetSpellData, it was resetting the stack before we pulled the variable so we got no variable data
- DoF client restricted to 20 slots for backpacks (by client limitation, enforced server side to avoid bugs)
- DoF bagged inventory now behaves correctly (bags were only showing items up to the 11th slot on login, DoF supports up to slot 20)
- Fixed mender having NO_RENT flag checked incorrectly not allowing individual repair of items (was checking flags vs flags2)

Emagi 6 months ago
parent
commit
14a74a1f45

+ 14 - 16
EQ2/source/WorldServer/Items/Items.cpp

@@ -2296,7 +2296,7 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 			}
 			case ITEM_TYPE_BAG:{
 				if(bag_info){
-					if (client->GetVersion() <= 283) {
+					if (client->GetVersion() <= 546) {
 						if (bag_info->num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
 							bag_info->num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;
 						packet->setSubstructDataByName("details", "num_slots", bag_info->num_slots);
@@ -2510,14 +2510,14 @@ void Item::serialize(PacketStruct* packet, bool show_name, Player* player, int16
 		Quest* quest = master_quest_list.GetQuest(generic_info.offers_quest_id, false);
 		if(quest){
 			packet->setSubstructDataByName("footer", "offers_quest", strlen(generic_info.offers_quest_name) ? generic_info.offers_quest_name : quest->GetName());
-			packet->setSubstructDataByName("footer", "quest_color", player->GetArrowColor(quest->GetQuestLevel()));
+			packet->setSubstructDataByName("footer", "offers_quest_color", player->GetArrowColor(quest->GetQuestLevel()));
 		}
 	}
 	if(generic_info.part_of_quest_id > 0){
 		Quest* quest = master_quest_list.GetQuest(generic_info.part_of_quest_id, false);
 		if(quest){
 			packet->setSubstructDataByName("footer", "part_of_quest", strlen(generic_info.required_by_quest_name) ? generic_info.required_by_quest_name : quest->GetName());
-			packet->setSubstructDataByName("footer", "quest_color", player->GetArrowColor(quest->GetQuestLevel()));
+			packet->setSubstructDataByName("footer", "part_of_quest_color", player->GetArrowColor(quest->GetQuestLevel()));
 		}
 	}
 	if(generic_info.max_charges > 0){
@@ -3177,10 +3177,7 @@ vector<Item*> PlayerItemList::GetAllItemsFromID(int32 id, bool include_bank, boo
 					if (slot_itr->second && slot_itr->second->details.item_id == id) {
 						if (lock)
 							MPlayerItems.releasereadlock(__FUNCTION__, __LINE__);
-						int32 yyy = 0;
 						ret.push_back(slot_itr->second);
-						
-						//return slot_itr->second;
 					}
 				}
 				
@@ -3527,7 +3524,6 @@ EQ2Packet* PlayerItemList::serialize(Player* player, int16 version){
 
 void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item* item, int16 i, bool overflow){
 	Client *client;
-	int8 tmp_subtype = 0;
 	if (!packet || !player)
 		return;
 	client = player->GetZone()->GetClientBySpawn(player);
@@ -3539,7 +3535,7 @@ void PlayerItemList::AddItemToPacket(PacketStruct* packet, Player* player, Item*
 		menu_data -= ITEM_MENU_TYPE_GENERIC;
 
 	if (item->details.num_slots > 0) {
-		if (packet->GetVersion() <= 283 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
+		if (packet->GetVersion() <= 546 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
 			item->details.num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;
 		menu_data += ITEM_MENU_TYPE_BAG;
 		if (item->details.num_free_slots == item->details.num_slots)
@@ -3758,7 +3754,7 @@ bool PlayerItemList::HasItem(int32 id, bool include_bank){
 }
 
 bool PlayerItemList::SharedBankAddAllowed(Item* item){
-	if(!item || item->CheckFlag(NO_TRADE) && item->CheckFlag2(HEIRLOOM) == 0)
+	if(!item || (item->CheckFlag(NO_TRADE) && (item->CheckFlag2(HEIRLOOM) == 0)))
 		return false;
 
 	MPlayerItems.readlock(__FUNCTION__, __LINE__);
@@ -4121,13 +4117,15 @@ Item* EquipmentItemList::GetItem(int8 slot_id){
 }
 
 void EquipmentItemList::SendEquippedItems(Player* player){
-	if(!player->GetClient())
+	if(!player->GetClient()) {
 		return;
-		for(int16 i=0;i<NUM_SLOTS;i++){
-			Item* item = items[i];
-			if(item && item->details.item_id > 0)
-				player->GetClient()->QueuePacket(item->serialize(player->GetClient()->GetVersion(), false, player));
-		}
+	}
+	
+	for(int16 i=0;i<NUM_SLOTS;i++){
+		Item* item = items[i];
+		if(item && item->details.item_id > 0)
+			player->GetClient()->QueuePacket(item->serialize(player->GetClient()->GetVersion(), false, player));
+	}
 }
 
 EQ2Packet* EquipmentItemList::serialize(int16 version, Player* player){
@@ -4163,7 +4161,7 @@ EQ2Packet* EquipmentItemList::serialize(int16 version, Player* player){
 				if(item->slot_data.size() > 0)
 					menu_data -= ITEM_MENU_TYPE_GENERIC;
 				if (item->details.num_slots > 0) {
-					if (packet->GetVersion() <= 283 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
+					if (packet->GetVersion() <= 546 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
 						item->details.num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;
 					menu_data += ITEM_MENU_TYPE_BAG;
 					if (item->details.num_free_slots == item->details.num_slots)

+ 59 - 13
EQ2/source/WorldServer/LuaFunctions.cpp

@@ -11609,10 +11609,16 @@ int EQ2Emu_lua_GetZoneHolidayFlag(lua_State* state) {
 int EQ2Emu_lua_SetCanBind(lua_State* state) {
 	if (!lua_interface)
 		return 0;
-	Spawn* player = lua_interface->GetSpawn(state);
-	ZoneServer* zone = player->GetZone();
+	Spawn* spawn = lua_interface->GetSpawn(state);
 	bool canbind = lua_interface->GetInt32Value(state, 2);
 	lua_interface->ResetFunctionStack(state);
+	
+	if(!spawn) {
+		lua_interface->LogError("%s: LUA SetCanBind command error: spawn is not valid", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	
+	ZoneServer* zone = spawn->GetZone();
 	if (zone)
 		zone->SetCanBind(canbind);
 	return 0;
@@ -11621,9 +11627,16 @@ int EQ2Emu_lua_SetCanBind(lua_State* state) {
 int EQ2Emu_lua_GetCanBind(lua_State* state) {
 	if (!lua_interface)
 		return 0;
-	Spawn* player = lua_interface->GetSpawn(state);
-	ZoneServer* zone = player->GetZone();
+	
+	Spawn* spawn = lua_interface->GetSpawn(state);
 	lua_interface->ResetFunctionStack(state);
+	
+	if(!spawn) {
+		lua_interface->LogError("%s: LUA GetCanBind command error: spawn is not valid", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	
+	ZoneServer* zone = spawn->GetZone();
 	if (zone) {
 		lua_interface->SetInt32Value(state, zone->GetCanBind());
 		return 1;
@@ -11634,10 +11647,17 @@ int EQ2Emu_lua_GetCanBind(lua_State* state) {
 int EQ2Emu_lua_SetCanGate(lua_State* state) {
 	if (!lua_interface)
 		return 0;
-	Spawn* player = lua_interface->GetSpawn(state);
-	ZoneServer* zone = player->GetZone();
+	
+	Spawn* spawn = lua_interface->GetSpawn(state);
 	bool cangate = lua_interface->GetInt32Value(state, 2);
 	lua_interface->ResetFunctionStack(state);
+	
+	if(!spawn) {
+		lua_interface->LogError("%s: LUA SetCanGate command error: spawn is not valid", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	
+	ZoneServer* zone = spawn->GetZone();
 	if (zone)
 		zone->SetCanGate(cangate);
 	return 0;
@@ -11646,9 +11666,16 @@ int EQ2Emu_lua_SetCanGate(lua_State* state) {
 int EQ2Emu_lua_GetCanGate(lua_State* state) {
 	if (!lua_interface)
 		return 0;
-	Spawn* player = lua_interface->GetSpawn(state);
-	ZoneServer* zone = player->GetZone();
+	
+	Spawn* spawn = lua_interface->GetSpawn(state);
 	lua_interface->ResetFunctionStack(state);
+	
+	if(!spawn) {
+		lua_interface->LogError("%s: LUA GetCanGate command error: spawn is not valid", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	
+	ZoneServer* zone = spawn->GetZone();
 	if (zone) {
 		lua_interface->SetInt32Value(state, zone->GetCanGate());
 		return 1;
@@ -11659,10 +11686,17 @@ int EQ2Emu_lua_GetCanGate(lua_State* state) {
 int EQ2Emu_lua_SetCanEvac(lua_State* state) {
 	if (!lua_interface)
 		return 0;
-	Spawn* player = lua_interface->GetSpawn(state);
-	ZoneServer* zone = player->GetZone();
+	
+	Spawn* spawn = lua_interface->GetSpawn(state);
 	bool canevac = lua_interface->GetInt32Value(state, 2);
 	lua_interface->ResetFunctionStack(state);
+	
+	if(!spawn) {
+		lua_interface->LogError("%s: LUA SetCanEvac command error: spawn is not valid", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	
+	ZoneServer* zone = spawn->GetZone();
 	if (zone)
 		zone->SetCanEvac(canevac);
 	return 0;
@@ -11671,9 +11705,16 @@ int EQ2Emu_lua_SetCanEvac(lua_State* state) {
 int EQ2Emu_lua_GetCanEvac(lua_State* state) {
 	if (!lua_interface)
 		return 0;
-	Spawn* player = lua_interface->GetSpawn(state);
-	ZoneServer* zone = player->GetZone();
+	
+	Spawn* spawn = lua_interface->GetSpawn(state);
 	lua_interface->ResetFunctionStack(state);
+	
+	if(!spawn) {
+		lua_interface->LogError("%s: LUA GetCanEvac command error: spawn is not valid", lua_interface->GetScriptName(state));
+		return 0;
+	}
+	
+	ZoneServer* zone = spawn->GetZone();
 	if (zone) {
 		lua_interface->SetInt32Value(state, zone->GetCanEvac());
 		return 1;
@@ -12066,15 +12107,16 @@ int EQ2Emu_lua_SetSpellData(lua_State* state) {
 		return 0;
 	LuaSpell* spell = lua_interface->GetSpell(state);
 	string field = lua_interface->GetStringValue(state, 2);
-	lua_interface->ResetFunctionStack(state);
 	int8 fieldArg = 3; // field value after the initial set
 
 	if (!spell) {
 		lua_interface->LogError("%s: Spell not given in SetSpellData!", lua_interface->GetScriptName(state));
+		lua_interface->ResetFunctionStack(state);
 		return 0;
 	}
 	if (!spell->spell || !spell->spell->GetSpellData()) {
 		lua_interface->LogError("%s: Inner Spell or SpellData not given in SetSpellData!", lua_interface->GetScriptName(state));
+		lua_interface->ResetFunctionStack(state);
 		return 0;
 	}
 
@@ -12083,6 +12125,7 @@ int EQ2Emu_lua_SetSpellData(lua_State* state) {
 	bool valSet = false;
 
 	spell->spell->SetSpellData(state, field, fieldArg);
+	lua_interface->ResetFunctionStack(state);
 
 	return valSet;
 }
@@ -12095,16 +12138,19 @@ int EQ2Emu_lua_SetSpellDataIndex(lua_State* state) {
 
 	if (!spell) {
 		lua_interface->LogError("%s: Spell not given in SetSpellDataIndex!", lua_interface->GetScriptName(state));
+		lua_interface->ResetFunctionStack(state);
 		return 0;
 	}
 	if (!spell->spell || !spell->spell->GetSpellData()) {
 		lua_interface->LogError("%s: Inner Spell or SpellData not given in SetSpellDataIndex!", lua_interface->GetScriptName(state));
+		lua_interface->ResetFunctionStack(state);
 		return 0;
 	}
 
 	if (spell->spell->lua_data.size() <= idx)
 	{
 		lua_interface->LogError("%s: lua_data size %i <= %i (idx passed) SetSpellDataIndex!", lua_interface->GetScriptName(state), spell->spell->lua_data.size(), idx);
+		lua_interface->ResetFunctionStack(state);
 		return 0;
 	}
 

+ 23 - 0
EQ2/source/WorldServer/Player.cpp

@@ -6592,15 +6592,38 @@ void PlayerControlFlags::SendControlFlagUpdates(Client* client){
 		for (itr2 = ptr->begin(); itr2 != ptr->end(); itr2++){
 			int32 param = itr2->first;
 			if(client->GetVersion() <= 546) {
+				if(itr->first == 1) { // first set of flags DoF only supports these
+					bool skip = false;
+					switch(itr2->first) {
+						case 1: // flymode for DoF
+						case 2: // no clip mode for DoF
+						case 4: // we don't know
+						case 32: { // safe fall (DoF is low gravity for this parameter)
+							skip = true;
+							break;
+						}
+					}
+				
+					if(skip) {
+						continue;
+					}
+				}
+				
+				bool bypassFlag = true;
+				// remap control effects to old DoF from AoM
 				switch(itr->first) {
 					case 4: {
 						if(itr2->first == 64) { // stun
 							ClientPacketFunctions::SendServerControlFlagsClassic(client, 8, itr2->second);
 							param = 16;
+							bypassFlag = false;
 						}
 						break;
 					}
 				}
+				if(itr->first > 1 && bypassFlag) {
+					continue; // we don't support flag sets higher than 1 for DoF
+				}
 				ClientPacketFunctions::SendServerControlFlagsClassic(client, param, itr2->second);
 			}
 			else {

+ 1 - 13
EQ2/source/WorldServer/Spawn.cpp

@@ -2298,19 +2298,7 @@ void Spawn::InitializePosPacketData(Player* player, PacketStruct* packet, bool b
 	if (!IsPlayer()) // has to be 2 or NPC's warp around when moving
 		packet->setDataByName("pos_movement_mode", 2);
 	
-	if(version <= 910)
-		packet->setDataByName("pos_unknown10", 0xFFFF, 1);
-	else if (version >= 1119)
-			packet->setDataByName("face_actor_id", 0xFFFFFFFF);
-	else
-		packet->setDataByName("pos_unknown10", 0xFFFF);
-
-	if(version <= 910)
-		packet->setDataByName("pos_unknown10", 0xFFFF, 2);
-	else if (version >= 1119)
-		packet->setDataByName("face_actor_id", 0xFFFFFFFF);
-	else
-		packet->setDataByName("pos_unknown10", 0XFFFF, 1);
+	packet->setDataByName("face_actor_id", 0xFFFFFFFF);
 
 	packet->setDataByName("pos_pitch1", appearance.pos.Pitch1);
 	packet->setDataByName("pos_pitch2", appearance.pos.Pitch2);

+ 3 - 2
EQ2/source/WorldServer/Tradeskills/Tradeskills.cpp

@@ -215,8 +215,9 @@ void TradeskillMgr::Process() {
 						}
 					}
 				}
-
-				client->QueuePacket(packet->serialize());
+				EQ2Packet* pack = packet->serialize();
+				packet->PrintPacket();
+				client->QueuePacket(pack);
 				safe_delete(packet);
 			}
 

+ 23 - 31
EQ2/source/WorldServer/client.cpp

@@ -522,18 +522,16 @@ void Client::DisplayDeadWindow()
 	player->SetPower(0);
 	GetCurrentZone()->TriggerCharSheetTimer();
 
-	PacketStruct* packet = configReader.getStruct("WS_ServerControlFlags", GetVersion());
-	if (packet)
-	{
-		packet->setDataByName("parameter1", 8);
-		packet->setDataByName("value", 1);
-		QueuePacket(packet->serialize());
-		packet->setDataByName("parameter1", 16);
-		QueuePacket(packet->serialize());
-		safe_delete(packet);
+	if(GetVersion() <= 546) {
+		ClientPacketFunctions::SendServerControlFlagsClassic(this, 8, 1);
+		ClientPacketFunctions::SendServerControlFlagsClassic(this, 16, 1);
+	}
+	else {
+		ClientPacketFunctions::SendServerControlFlags(this, 1, 8, 1);
+		ClientPacketFunctions::SendServerControlFlags(this, 1, 16, 1);
 	}
 
-	packet = configReader.getStruct("WS_ServerUpdateTarget", GetVersion());
+	PacketStruct* packet = configReader.getStruct("WS_ServerUpdateTarget", GetVersion());
 	if (packet)
 	{
 		packet->setDataByName("spawn_id", 0xFFFFFFFF);
@@ -547,18 +545,17 @@ void Client::DisplayDeadWindow()
 
 void Client::HandlePlayerRevive(int32 point_id)
 {
-	PacketStruct* packet = configReader.getStruct("WS_ServerControlFlags", GetVersion());
-	if (packet)
-	{
-		packet->setDataByName("parameter1", 8);
-		QueuePacket(packet->serialize());
-		packet->setDataByName("parameter1", 16);
-		QueuePacket(packet->serialize());
-		safe_delete(packet);
+	if(GetVersion() <= 546) {
+		ClientPacketFunctions::SendServerControlFlagsClassic(this, 8, 0);
+		ClientPacketFunctions::SendServerControlFlagsClassic(this, 16, 0);
+	}
+	else {
+		ClientPacketFunctions::SendServerControlFlags(this, 1, 8, 0);
+		ClientPacketFunctions::SendServerControlFlags(this, 1, 16, 0);
 	}
 
 	SimpleMessage(CHANNEL_NARRATIVE, "You regain consciousness!");
-	packet = configReader.getStruct("WS_Resurrected", GetVersion());
+	PacketStruct* packet = configReader.getStruct("WS_Resurrected", GetVersion());
 	if (packet)
 	{
 		QueuePacket(packet->serialize());
@@ -2161,7 +2158,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	}
 	case OP_BuyPlayerHouseMsg: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_BuyPlayerHouseMsg", opcode, opcode);
-		DumpPacket(app);
+		//DumpPacket(app);
 		int64 bank_money = GetPlayer()->GetBankCoinsPlat();
 		PacketStruct* packet = configReader.getStruct("WS_BuyHouse", GetVersion());
 		if (packet) {
@@ -2245,7 +2242,7 @@ bool Client::HandlePacket(EQApplicationPacket* app) {
 	}
 	case OP_EnterHouseMsg: {
 		LogWrite(OPCODE__DEBUG, 1, "Opcode", "Opcode 0x%X (%i): OP_EnterHouseMsg", opcode, opcode);
-		DumpPacket(app);
+		//DumpPacket(app);
 		PacketStruct* packet = configReader.getStruct("WS_EnterHouse", GetVersion());
 		if (packet) {
 			if(packet->LoadPacketData(app->pBuffer, app->size)) {
@@ -7085,10 +7082,6 @@ bool Client::AddItem(Item* item, bool* item_deleted, AddItemType type) {
 	if (!item) {
 		return false;
 	}
-	if (item->IsBag()) {
-		if (GetVersion() <= 283 && item->details.num_slots > CLASSIC_EQ_MAX_BAG_SLOTS)
-			item->details.num_slots = CLASSIC_EQ_MAX_BAG_SLOTS;		
-	}
 	if (player->AddItem(item, type)) {
 		EQ2Packet* outapp = player->SendInventoryUpdate(GetVersion());
 		if (outapp) {
@@ -7681,7 +7674,7 @@ void Client::RepairItem(int32 item_id) {
 		if (!item)
 			item = player->GetEquipmentList()->GetItemFromItemID(item_id);
 		if (item) {
-			if(item->CheckFlag(NO_REPAIR)) {
+			if(item->CheckFlag2(NO_REPAIR)) {
 				Message(CHANNEL_MERCHANT, "The mender was unable to repair your items.");
 				PlaySound("buy_failed");
 			}
@@ -8251,7 +8244,7 @@ void Client::SendRepairList() {
 					packet->setArrayDataByName("description", item->description.c_str(), i);
 			}
 			if (GetVersion() <= 546) {
-				packet->setDataByName("type", 0);
+				packet->setDataByName("type", 112);
 			}
 			else {
 				packet->setDataByName("type", 96);
@@ -8261,11 +8254,11 @@ void Client::SendRepairList() {
 			//DumpPacket(outapp);
 			QueuePacket(outapp);
 			
-			if (GetVersion() <= 546) {
+			/*if (GetVersion() <= 546) {
 				packet->setDataByName("type", 16);
 				EQ2Packet* outapp2 = packet->serialize();
 				QueuePacket(outapp2);
-			}
+			}*/
 			
 			safe_delete(packet);
 		}
@@ -9356,7 +9349,6 @@ void Client::SearchStore(int32 page) {
 					packet->setArrayDataByName("item_id", item->details.item_id, i);
 					packet->setArrayDataByName("item_id2", item->details.item_id, i);
 					packet->setArrayDataByName("icon", item->details.icon, i);
-					packet->setArrayDataByName("unknown15", 1, i, World::newValue);
 					//packet->setArrayDataByName("unknown2b", i, i);
 					packet->setArrayDataByName("item_seller_id", 1, i);
 					if (item->stack_count == 0)
@@ -10343,7 +10335,7 @@ void Client::SendRecipeList() {
 			packet->setArrayDataByName("unknown", 0x7005BE3, i); //0x7005BE3
 			i++;
 		}
-		packet->PrintPacket();
+		//packet->PrintPacket();
 		EQ2Packet* ret = packet->serializeCountPacket(GetVersion(), 0, nullptr, nullptr);
 		QueuePacket(ret);
 		safe_delete(packet);

+ 10 - 9
EQ2/source/WorldServer/zoneserver.cpp

@@ -7236,6 +7236,7 @@ void ZoneServer::ResurrectSpawn(Spawn* spawn, Client* client) {
 	if(power_amt > spawn->GetTotalPower())
 		power_amt = spawn->GetTotalPower();
 
+	spawn->SetAlive(true);
 	spawn->SetHP(heal_amt);
 	if(power_amt > 0)
 		spawn->SetPower(power_amt);
@@ -7271,16 +7272,16 @@ void ZoneServer::ResurrectSpawn(Spawn* spawn, Client* client) {
 			if(packet){
 				client->QueuePacket(packet->serialize());
 			}
-			packet = configReader.getStruct("WS_ServerControlFlags", client->GetVersion());
-			if(packet)
-			{
-				packet->setDataByName("parameter1", 8);
-				client->QueuePacket(packet->serialize());
-				packet->setDataByName("parameter1", 16);
-				client->QueuePacket(packet->serialize());
-			}
-
 			safe_delete(packet);
+			
+			if(client->GetVersion() <= 546) {
+				ClientPacketFunctions::SendServerControlFlagsClassic(client, 8, 0);
+				ClientPacketFunctions::SendServerControlFlagsClassic(client, 16, 0);
+			}
+			else {
+				ClientPacketFunctions::SendServerControlFlags(client, 1, 8, 0);
+				ClientPacketFunctions::SendServerControlFlags(client, 1, 16, 0);
+			}
 			client->SimpleMessage(CHANNEL_NARRATIVE, "You regain consciousness!");
 		}
 	}

+ 7 - 7
server/SpawnScripts/Generic/SpiritShard.lua

@@ -42,13 +42,13 @@ function recovershard(NPC, Spawn)
 end
 
 function CheckShardExpired(NPC)
-	local creationStamp = GetShardCreatedTimestamp(NPC)
-	local year_ = math.floor(string.sub(creationStamp, 0, 4))
-	local month_ = math.floor(string.sub(creationStamp, 5, 6))
-	local day_ = math.floor(string.sub(creationStamp, 7, 8))
-	local hour_ = math.floor(string.sub(creationStamp, 9, 10))
-	local min_ = math.floor(string.sub(creationStamp, 11, 12))
-	local sec_ = math.floor(string.sub(creationStamp, 13, 14))
+	local creationStamp = tostring(GetShardCreatedTimestamp(NPC))
+	local year_ = math.floor(tonumber(string.sub(creationStamp, 0, 4)))
+	local month_ = math.floor(tonumber(string.sub(creationStamp, 5, 6)))
+	local day_ = math.floor(tonumber(string.sub(creationStamp, 7, 8)))
+	local hour_ = math.floor(tonumber(string.sub(creationStamp, 9, 10)))
+	local min_ = math.floor(tonumber(string.sub(creationStamp, 11, 12)))
+	local sec_ = math.floor(tonumber(string.sub(creationStamp, 13, 14)))
 	local currentUTCTime = os.time(os.date('!*t'))
 	local creationTime = os.time{year=year_, month=month_, day=day_, hour=hour_, min=min_,sec=sec_}
 	

+ 2 - 2
server/SpawnStructs.xml

@@ -137,13 +137,13 @@
 <Data ElementName="pos_x" Type="float" Size="1" /> <!-- 0x3c -->
 <Data ElementName="pos_y" Type="float" Size="1" /> <!-- 0x40 -->
 <Data ElementName="pos_z" Type="float" Size="1" /> <!-- 0x44 -->
-<Data ElementName="pos_pitch" Type="sint16" Size="1" /> <!-- 0x48 -->
+<Data ElementName="pos_pitch2" Type="sint16" Size="1" /> <!-- 0x48 -->
 <Data ElementName="pos_collision_radius" Type="sint16" Size="1" /> <!-- 0x4a -->
 <Data ElementName="pos_size" Type="sint16" Size="1" /> <!-- 0x4c -->
 <Data ElementName="pos_unknown3" Type="sint16" Size="1" /> <!-- 0x4e -->
 <Data ElementName="face_actor_id" Type="int32" Size="1" /> <!-- 0x50 -->
 <Data ElementName="actor_stop_range" Type="sint16" Size="1" /> <!-- 0x54 -->
-<Data ElementName="pos_unknown4" Type="sint16" Size="1" /> <!-- 0x56 -->
+<Data ElementName="pos_roll" Type="sint16" Size="1" /> <!-- 0x56 -->
 </Struct>
 <Struct Name="Substruct_SpawnPositionStruct" ClientVersion="547">
 <Data ElementName="pos_grid_id" Type="int32" Size="1" />

+ 25 - 10
server/WorldStructs.xml

@@ -9819,17 +9819,25 @@ to zero and treated like placeholders." />
     <Data ElementName="item_id" Type="int64" Size="1" />
     <Data ElementName="quantity" Type="int32" Size="1" />
     <Data ElementName="unknown15x" Type="int8" Size="4" />
+    <Data ElementName="string_two" Type="EQ2_16Bit_String" Size="1" />
+    <Data ElementName="string_x" Type="EQ2_16Bit_String" Size="1" />
+    <Data ElementName="unknown15y" Type="int8" Size="6" />
+	<Data ElementName="stack_size" Type="int16" Size="1" />
+	<Data ElementName="unknown3" Type="int8" Size="14" />
+	<Data ElementName="icon" Type="int16" Size="1" />
     <Data ElementName="item_name" Type="EQ2_16Bit_String" Size="1" />
-    <Data ElementName="string_one" Type="EQ2_16Bit_String" Size="1" />
-    <Data ElementName="unknown15y" Type="int8" Size="28" />
-    <Data ElementName="sell_price" Type="int64" Size="1" />
-    <Data ElementName="unknown15spacex" Type="int8" Size="28" />
+    <Data ElementName="unknown15x" Type="int8" Size="2" />
+	<Data ElementName="sell_price" Type="int64" Size="1" />
+    <Data ElementName="unknown15spacey" Type="int8" Size="28" />
     <Data ElementName="seller_name" Type="EQ2_16Bit_String" Size="1" />
     <Data ElementName="icon" Type="int16" Size="1" />
     <Data ElementName="unknown" Type="int8" Size="10" />
 </Data>
+<Data ElementName="unknown" Type="int32" Size="1" />
+<Data ElementName="num_pages" Type="int32" Size="1" />
+<Data ElementName="per_page" Type="int32" Size="1" />
+<Data ElementName="page" Type="int32" Size="1" />
 </Struct>
-
 <Struct Name="WS_BrokerItems" ClientVersion="972" OpcodeName="OP_ClientCmdMsg" OpcodeType="OP_EqConsignmentItemsCmd" >
 <Data ElementName="unknown" Type="int8" />
 <Data ElementName="num_items" Type="int32" />
@@ -15958,12 +15966,7 @@ to zero and treated like placeholders." />
 <Data ElementName="num_process" Type="int16" Size="1" />
 <Data ElementName="process_array" Type="Array" ArraySizeVariable="num_process">
   <Data ElementName="progress_needed" Type="int32" Size="1" />
-  <Data ElementName="unknown3" Type="int8" Size="1" IfVariableNotSet="progress_needed"/>
-  <Data ElementName="item_name" Type="EQ2_16Bit_String" />
   <Data ElementName="item_icon" Type="int16" />
-  <Data ElementName="item" Type="EQ2_Item" />
-  <Data ElementName="item_byproduct_name" Type="EQ2_16Bit_String" />
-  <Data ElementName="item_byproduct_icon" Type="int16" />
   <!-- Another EQ2_Item? Does subtype set to FF prevent the rest of the packet?-->
   <!-- If not an EQ2_item this unknown *might* be quantity-->
   <Data ElementName="item_byproduct_unknown" Type="int16" />
@@ -16500,6 +16503,18 @@ to zero and treated like placeholders." />
 <Data ElementName="spawn_id" Type="int32" Size="1" />
 <Data ElementName="unknown" Type="int8" Size="1" />
 </Struct>
+<Struct Name="WS_UpdateCreateItem" ClientVersion="547" OpcodeName="OP_UpdateItemCreationProcessUIMsg">
+<Data ElementName="effect" Type="int8" Size="1" />
+<Data ElementName="total_durability" Type="int32" Size="1" />
+<Data ElementName="total_progress" Type="int32" Size="1" />
+<Data ElementName="progress_level" Type="int8" Size="1" />
+<Data ElementName="reaction_icon" Type="int16" Size="1" />
+<Data ElementName="reaction_name" Type="EQ2_16Bit_String" />
+<Data ElementName="durability_change" Type="sint32" Size="1" />
+<Data ElementName="progress_change" Type="sint32" Size="1" />
+<Data ElementName="spawn_id" Type="int32" Size="1" />
+<Data ElementName="unknown" Type="int8" Size="1" />
+</Struct>
 <Struct Name="WS_BeginItemCreation" ClientVersion="1" OpcodeName="OP_BeginItemCreationMsg">
 <Data ElementName="unknown1" Type="int32" Size="1" />
 <Data ElementName="primary_component_id" Type="int32" Size="1" />