This needs some improvements, because:
1) Sometimes the cell authority sends the death animation too late and a different one gets played on the other clients
2) There is probably a simpler check that can be done for position changes during a death animation.
Previously, it was possible for a Container packet to clear all equipment slots for an actor without the actor's authority then sending an equipment packet to correct that, due to packet loss or sudden disconnection, leading to actors not wearing any equipment as soon as they acquired a new authority.
This ensures that newly initialized LocalActors will now autoEquip.
Previously, a Container packet with a SET action for an actor would clear their entire InventoryStore, also clearing all of their equipment slots. The actor's authority would then autoEquip new equipment for the actor, but that new equipment would not actually get sent to the other players. As a result, they would see the actor fighting with hand-to-hand attacks, while also not actually wearing anything despite being rendered as wearing the same clothes and armor as before.
This commit makes the actor's authority resend the actor's equipment as soon as the Container packet has caused the autoEquip to happen.
Previously, certain errors early in the program's execution – such as an attempt to use two different packet processors for the same packet ID – would not be displayed because of a crash when attempting to get an uninitialized mwmp::Main in the Engine's destructor.
When determining actors siding with someone, also check the team members of DedicatedPlayers, not just those of the LocalPlayer.
Don't set players as each other's hitAttemptActor if they are team members.
Don't run startCombat() for DedicatedPlayers who get attacked.
Previously, creatures with fast attack animations would have their attack updated right after being started, which happened so quickly that it prevented the attack start from actually being sent by the client.
Previously, each client chose its own attack animations for DedicatedPlayers and DedicatedActors based on the direction they were walking in, which however led to desyncs for players with "Always Use Best Attack" enabled and for creatures which pick their attack animations randomly.
When Koncord implemented spellcasting, he made it so only the act of initiating a spellcast was synchronized, leaving it to other clients to actually cast a spell for a dedicated player or actor once their spellcasting animation was over. This had led to a lot of desyncs and has always been inconsistent with the handling of attacks, so I've belatedly gone ahead and prevented the end of a spellcasting animation from having any effect for dedicated players and actors, making them cast a spell when an appropriate Cast packet is received from them instead.
Additionally, the logged messages in MechanicsHelper's handling of attacking and casting have been moved around slightly.
This means the server scripts are now required to send a WorldKillCount packet as a reply to ActorDeath packets sent by clients. This gives the server full control over which kills are counted, while also solving the previous problem of kills being counted only for actors that had finished their death animations.
Rename the old WorldKillCount that was a Player packet into PlayerPlaceholder. Rename the unused CellCreate that was a Worldstate packet into WorldKillCount. On the server, move kill count-related script functions from QuestFunctions to WorldstateFunctions.
Previously, using CellController::getCellStore() to get an unloaded CellStore would make its references get loaded in the process, with the CellStore's loadRefs() then running updateMergedRefs(), which in turn – before getting as far as setting the CellStore's state to State_Loaded – would call CellController::hasLocalAuthority() on its accompanying ESM::Cell, which would then run CellController::isActiveWorldCell(), which would then run CellController::getCellStore() to get the CellStore again, which – still being marked as unloaded – would run the whole loop again... and again.
For starters, the new packet can set which client scripts have all of their variables synchronized between players. The previous hardcoded list of IDs for synchronized scripts has been removed.
Previously, creatures with fast spellcasting animations would cast their spells before their success had actually been calculated, causing them to fail.
Dead players will now show up at the correct cell and position for living players, making server scripts that allow players to revive each other much more functional.
Originally, the PlayerSkill packet contained skills, attribute increases and level progress. In 78441c769a, the attribute increases were moved to the PlayerAttribute packet and the level progress was moved to the PlayerLevel packet, but – due to an oversight – attribute increases and level progress were still being applied to the local player only when a PlayerSkill packet was received, based on whatever values were stored from the last PlayerAttribute and PlayerLevel packets.
Previously, multiple stacks of the same item ID could overwrite data in each other because of how the logic in ContainerStore::add() works. For example, a stack of 5 grand soul gems with no souls would get added to the player, then the attempt to add a grand soul gem with a particular soul would retrieve the previous stack first before setting all of it to that soul, resulting in 6 grand soul gems with that soul.
Enchanted inventory items continuously recharge their enchantment charges, which getItemPtrFromStore() should account for.
Additionally, prevent framelistener errors caused by PlayerItemUse packets about non-existent items.
Previously, client mods adding packet-sending scripts to the spawn area made clients send the associated packets as soon as they inputted their character name when joining a server using those mods. This made the clients either get disconnected for not replying to a handshake first, or it made them get kicked for sending object packets that are disallowed for players who are not logged in.
To fix this, LocalPlayer's hasFinishedCharGen() has been replaced with isLoggedIn(), because the former was already returning true when players inputted their names.
Previously, the player's currently selected weapon was being used in ranged attacks as in the original melee-oriented attack sync, which meant that shooting one type of projectile and then equipping another while the old projectile was still in the air turned the old projectile into the new projectile upon impact.
Additionally, avoid running most of the code in MechanicsHelper::assignAttackTarget() for non-hitting melee and ranged attacks.
Projectile hits now send Attack packets with RANGED attacks, and their success or failure is now synchronized.
Strike enchantments no longer require a valid victim to be synchronized.
Additional debug messages have been added for attacks.
Whenever an item is added to or removed from the player's ContainerStore, that player sends a PlayerInventory packet with just that addition or removal.
This eliminates all the unnecessary packet spam related to oversized PlayerInventory packets that had existed in one form or another since the initial implementation of inventory sync in 1b259e2d33
Additionally, move booleans from BasePlayer to LocalPlayer when they are only needed on the client, and make the usage of the isReceivingQuickKeys boolean consistent with the new isReceivingInventory boolean by having them both in the processors of their associated packets.
For a long time, whenever a PlayerInventory packet was sent, it contained all the items in the player's inventory, because that's how Koncord originally implemented it and I always had too many other priorities to go back and rework it.
From now on, clients only send PlayerInventory packet with the one item added or removed, with the single exception being trading with merchants, where the entire inventory is still sent for the time being.
When LocalActors briefly become DedicatedActors as the result of a server script, the DedicatedActors are immediately uninitialized to avoid bugs like them jumping in place or rotating slightly.
Additionally, the playing of animations and sounds received in packets for DedicatedActors is no longer done during their next update, but is instead done instantly when the packets are received.
The variable equipmentItem is identical to currentItem, so it should not have been added in commit 58a6a8c3bc
Addditionally, use a more descriptive variable name than "a" for item Ptrs.