forked from mirror/openmw-tes3mp
Merge pull request #402 from TES3MP/0.6.3
Add 0.6.3 commits up to 5 Apr 2018
This commit is contained in:
commit
c3b44e11fb
9 changed files with 142 additions and 30 deletions
|
@ -373,7 +373,20 @@ namespace MWClass
|
|||
}
|
||||
|
||||
// Apply "On hit" enchanted weapons
|
||||
MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
|
||||
|
||||
/*
|
||||
Start of tes3mp change (minor)
|
||||
|
||||
Track whether the strike enchantment is successful for attacks by the
|
||||
LocalPlayer or LocalActors
|
||||
*/
|
||||
bool appliedEnchantment = MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
|
||||
|
||||
if (localAttack)
|
||||
localAttack->applyWeaponEnchantment = appliedEnchantment;
|
||||
/*
|
||||
End of tes3mp change (minor)
|
||||
*/
|
||||
}
|
||||
else if (isBipedal(ptr))
|
||||
{
|
||||
|
|
|
@ -706,7 +706,20 @@ namespace MWClass
|
|||
damage *= store.find("fCombatKODamageMult")->getFloat();
|
||||
|
||||
// Apply "On hit" enchanted weapons
|
||||
MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
|
||||
|
||||
/*
|
||||
Start of tes3mp change (minor)
|
||||
|
||||
Track whether the strike enchantment is successful for attacks by the
|
||||
LocalPlayer or LocalActors
|
||||
*/
|
||||
bool appliedEnchantment = MWMechanics::applyOnStrikeEnchantment(ptr, victim, weapon, hitPosition);
|
||||
|
||||
if (localAttack)
|
||||
localAttack->applyWeaponEnchantment = appliedEnchantment;
|
||||
/*
|
||||
End of tes3mp change (minor)
|
||||
*/
|
||||
|
||||
MWMechanics::applyElementalShields(ptr, victim);
|
||||
|
||||
|
|
|
@ -290,10 +290,29 @@ namespace MWMechanics
|
|||
reduceWeaponCondition(damage, validVictim, weapon, attacker);
|
||||
|
||||
// Apply "On hit" effect of the weapon & projectile
|
||||
|
||||
/*
|
||||
Start of tes3mp change (minor)
|
||||
|
||||
Track whether the strike enchantment is successful for attacks by the
|
||||
LocalPlayer or LocalActors for both their weapon and projectile
|
||||
*/
|
||||
mwmp::Attack *localAttack = MechanicsHelper::getLocalAttack(attacker);
|
||||
|
||||
bool appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, weapon, hitPosition, true);
|
||||
|
||||
if (localAttack)
|
||||
localAttack->applyWeaponEnchantment = appliedEnchantment;
|
||||
|
||||
if (weapon != projectile)
|
||||
appliedEnchantment = applyOnStrikeEnchantment(attacker, victim, projectile, hitPosition, true);
|
||||
|
||||
if (localAttack)
|
||||
localAttack->applyProjectileEnchantment = appliedEnchantment;
|
||||
/*
|
||||
End of tes3mp change (minor)
|
||||
*/
|
||||
|
||||
if (validVictim)
|
||||
{
|
||||
// Non-enchanted arrows shot at enemies have a chance to turn up in their inventory
|
||||
|
|
|
@ -86,13 +86,10 @@ Attack *MechanicsHelper::getDedicatedAttack(const MWWorld::Ptr& ptr)
|
|||
|
||||
MWWorld::Ptr MechanicsHelper::getPlayerPtr(const Target& target)
|
||||
{
|
||||
if (target.refId.empty())
|
||||
{
|
||||
if (target.guid == mwmp::Main::get().getLocalPlayer()->guid)
|
||||
return MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
else if (PlayerList::getPlayer(target.guid) != nullptr)
|
||||
return PlayerList::getPlayer(target.guid)->getPtr();
|
||||
}
|
||||
if (target.guid == mwmp::Main::get().getLocalPlayer()->guid)
|
||||
return MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
else if (PlayerList::getPlayer(target.guid) != nullptr)
|
||||
return PlayerList::getPlayer(target.guid)->getPtr();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -101,18 +98,19 @@ void MechanicsHelper::assignAttackTarget(Attack* attack, const MWWorld::Ptr& tar
|
|||
{
|
||||
if (target == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
{
|
||||
attack->target.isPlayer = true;
|
||||
attack->target.guid = mwmp::Main::get().getLocalPlayer()->guid;
|
||||
attack->target.refId.clear();
|
||||
}
|
||||
else if (mwmp::PlayerList::isDedicatedPlayer(target))
|
||||
{
|
||||
attack->target.isPlayer = true;
|
||||
attack->target.guid = mwmp::PlayerList::getPlayer(target)->guid;
|
||||
attack->target.refId.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWWorld::CellRef *targetRef = &target.getCellRef();
|
||||
|
||||
attack->target.isPlayer = false;
|
||||
attack->target.refId = targetRef->getRefId();
|
||||
attack->target.refNumIndex = targetRef->getRefNum().mIndex;
|
||||
attack->target.mpNum = targetRef->getMpNum();
|
||||
|
@ -124,8 +122,12 @@ void MechanicsHelper::resetAttack(Attack* attack)
|
|||
attack->success = false;
|
||||
attack->knockdown = false;
|
||||
attack->block = false;
|
||||
attack->applyWeaponEnchantment = false;
|
||||
attack->applyProjectileEnchantment = false;
|
||||
attack->target.guid = RakNet::RakNetGUID();
|
||||
attack->target.refId.clear();
|
||||
attack->target.refNumIndex = 0;
|
||||
attack->target.mpNum = 0;
|
||||
}
|
||||
|
||||
bool MechanicsHelper::getSpellSuccess(std::string spellId, const MWWorld::Ptr& caster)
|
||||
|
@ -150,7 +152,7 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
|
|||
|
||||
MWWorld::Ptr victim;
|
||||
|
||||
if (attack.target.refId.empty())
|
||||
if (attack.target.isPlayer)
|
||||
{
|
||||
if (attack.target.guid == mwmp::Main::get().getLocalPlayer()->guid)
|
||||
victim = MWBase::Environment::get().getWorld()->getPlayerPtr();
|
||||
|
@ -170,14 +172,20 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
|
|||
if (attack.type == Attack::Type::Melee)
|
||||
{
|
||||
MWWorld::Ptr weapon;
|
||||
MWWorld::Ptr projectile;
|
||||
|
||||
if (attacker.getClass().hasInventoryStore(attacker))
|
||||
{
|
||||
MWWorld::InventoryStore &inv = attacker.getClass().getInventoryStore(attacker);
|
||||
MWWorld::ContainerStoreIterator weaponslot = inv.getSlot(
|
||||
MWWorld::InventoryStore &inventoryStore = attacker.getClass().getInventoryStore(attacker);
|
||||
MWWorld::ContainerStoreIterator weaponSlot = inventoryStore.getSlot(
|
||||
MWWorld::InventoryStore::Slot_CarriedRight);
|
||||
MWWorld::ContainerStoreIterator projectileSlot = inventoryStore.getSlot(
|
||||
MWWorld::InventoryStore::Slot_Ammunition);
|
||||
|
||||
// TODO: Fix for when arrows, bolts and throwing weapons have just run out
|
||||
weapon = weaponSlot != inventoryStore.end() ? *weaponSlot : MWWorld::Ptr();
|
||||
projectile = projectileSlot != inventoryStore.end() ? *projectileSlot : MWWorld::Ptr();
|
||||
|
||||
weapon = ((weaponslot != inv.end()) ? *weaponslot : MWWorld::Ptr());
|
||||
if (!weapon.isEmpty() && weapon.getTypeName() != typeid(ESM::Weapon).name())
|
||||
weapon = MWWorld::Ptr();
|
||||
}
|
||||
|
@ -195,8 +203,26 @@ void MechanicsHelper::processAttack(Attack attack, const MWWorld::Ptr& attacker)
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_APPEND(Log::LOG_VERBOSE, "- weapon: %s", weapon.getCellRef().getRefId().c_str());
|
||||
|
||||
MWMechanics::blockMeleeAttack(attacker, victim, weapon, attack.damage, 1);
|
||||
|
||||
if (attack.applyWeaponEnchantment)
|
||||
{
|
||||
MWMechanics::CastSpell cast(attacker, victim, false);
|
||||
cast.mHitPosition = osg::Vec3f();
|
||||
cast.cast(weapon, false);
|
||||
}
|
||||
|
||||
if (attack.applyProjectileEnchantment)
|
||||
{
|
||||
MWMechanics::CastSpell cast(attacker, victim, false);
|
||||
cast.mHitPosition = osg::Vec3f();
|
||||
cast.cast(projectile, false);
|
||||
}
|
||||
}
|
||||
|
||||
victim.getClass().onHit(victim, attack.damage, healthdmg, weapon, attacker, osg::Vec3f(),
|
||||
attack.success);
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ void WorldEvent::addContainerItem(mwmp::WorldObject& worldObject, const MWWorld:
|
|||
containerItem.enchantmentCharge = itemPtr.getCellRef().getEnchantmentCharge();
|
||||
containerItem.actionCount = actionCount;
|
||||
|
||||
LOG_APPEND(Log::LOG_INFO, "- Adding container item %s", containerItem.refId.c_str());
|
||||
LOG_APPEND(Log::LOG_INFO, "-- Adding container item %s", containerItem.refId.c_str());
|
||||
|
||||
worldObject.containerItems.push_back(containerItem);
|
||||
}
|
||||
|
@ -223,7 +223,12 @@ void WorldEvent::editContainers(MWWorld::CellStore* cellStore)
|
|||
mwmp::Main::get().getCellController()->isLocalActor(ptrFound))
|
||||
{
|
||||
MWWorld::InventoryStore& invStore = ptrFound.getClass().getInventoryStore(ptrFound);
|
||||
invStore.autoEquip(ptrFound);
|
||||
|
||||
if (ptrFound.getTypeName() == typeid(ESM::NPC).name())
|
||||
invStore.autoEquip(ptrFound);
|
||||
// autoEquip only works on NPCs, so use the closest alternative for creatures
|
||||
else
|
||||
invStore.autoEquipShield(ptrFound);
|
||||
}
|
||||
|
||||
// If this container was open for us, update its view
|
||||
|
@ -324,7 +329,7 @@ void WorldEvent::spawnObjects(MWWorld::CellStore* cellStore)
|
|||
{
|
||||
MWWorld::Ptr masterPtr;
|
||||
|
||||
if (worldObject.master.refId.empty())
|
||||
if (worldObject.master.isPlayer)
|
||||
masterPtr = MechanicsHelper::getPlayerPtr(worldObject.master);
|
||||
else
|
||||
masterPtr = cellStore->searchExact(worldObject.master.refNumIndex, worldObject.master.mpNum);
|
||||
|
@ -814,18 +819,19 @@ void WorldEvent::addObjectSpawn(const MWWorld::Ptr& ptr, const MWWorld::Ptr& mas
|
|||
|
||||
if (master == MWBase::Environment::get().getWorld()->getPlayerPtr())
|
||||
{
|
||||
worldObject.master.isPlayer = true;
|
||||
worldObject.master.guid = mwmp::Main::get().getLocalPlayer()->guid;
|
||||
worldObject.master.refId.clear();
|
||||
}
|
||||
else if (mwmp::PlayerList::isDedicatedPlayer(master))
|
||||
{
|
||||
worldObject.master.isPlayer = true;
|
||||
worldObject.master.guid = mwmp::PlayerList::getPlayer(master)->guid;
|
||||
worldObject.master.refId.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
MWWorld::CellRef *masterRef = &master.getCellRef();
|
||||
|
||||
worldObject.master.isPlayer = false;
|
||||
worldObject.master.refId = masterRef->getRefId();
|
||||
worldObject.master.refNumIndex = masterRef->getRefNum().mIndex;
|
||||
worldObject.master.mpNum = masterRef->getMpNum();
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace mwmp
|
|||
|
||||
struct Target
|
||||
{
|
||||
bool isPlayer;
|
||||
|
||||
std::string refId;
|
||||
int refNumIndex;
|
||||
int mpNum;
|
||||
|
@ -66,6 +68,8 @@ namespace mwmp
|
|||
bool pressed;
|
||||
bool instant;
|
||||
bool knockdown;
|
||||
bool applyWeaponEnchantment;
|
||||
bool applyProjectileEnchantment;
|
||||
|
||||
bool shouldSend;
|
||||
};
|
||||
|
|
|
@ -11,9 +11,18 @@ PacketActorAttack::PacketActorAttack(RakNet::RakPeerInterface *peer) : ActorPack
|
|||
|
||||
void PacketActorAttack::Actor(BaseActor &actor, bool send)
|
||||
{
|
||||
RW(actor.attack.target.refNumIndex, send);
|
||||
RW(actor.attack.target.mpNum, send);
|
||||
RW(actor.attack.target.guid, send);
|
||||
RW(actor.attack.target.isPlayer, send);
|
||||
|
||||
if (actor.attack.target.isPlayer)
|
||||
{
|
||||
RW(actor.attack.target.guid, send);
|
||||
}
|
||||
else
|
||||
{
|
||||
RW(actor.attack.target.refId, send, 1);
|
||||
RW(actor.attack.target.refNumIndex, send);
|
||||
RW(actor.attack.target.mpNum, send);
|
||||
}
|
||||
|
||||
RW(actor.attack.spellId, send);
|
||||
RW(actor.attack.type, send);
|
||||
|
@ -25,4 +34,6 @@ void PacketActorAttack::Actor(BaseActor &actor, bool send)
|
|||
RW(actor.attack.block, send);
|
||||
|
||||
RW(actor.attack.instant, send);
|
||||
RW(actor.attack.applyWeaponEnchantment, send);
|
||||
RW(actor.attack.applyProjectileEnchantment, send);
|
||||
}
|
||||
|
|
|
@ -16,10 +16,18 @@ void PacketPlayerAttack::Packet(RakNet::BitStream *bs, bool send)
|
|||
{
|
||||
PlayerPacket::Packet(bs, send);
|
||||
|
||||
RW(player->attack.target.refId, send, 1);
|
||||
RW(player->attack.target.refNumIndex, send);
|
||||
RW(player->attack.target.mpNum, send);
|
||||
RW(player->attack.target.guid, send);
|
||||
RW(player->attack.target.isPlayer, send);
|
||||
|
||||
if (player->attack.target.isPlayer)
|
||||
{
|
||||
RW(player->attack.target.guid, send);
|
||||
}
|
||||
else
|
||||
{
|
||||
RW(player->attack.target.refId, send, 1);
|
||||
RW(player->attack.target.refNumIndex, send);
|
||||
RW(player->attack.target.mpNum, send);
|
||||
}
|
||||
|
||||
RW(player->attack.spellId, send, 1);
|
||||
RW(player->attack.type, send);
|
||||
|
@ -29,4 +37,7 @@ void PacketPlayerAttack::Packet(RakNet::BitStream *bs, bool send)
|
|||
RW(player->attack.pressed, send);
|
||||
RW(player->attack.knockdown, send);
|
||||
RW(player->attack.block, send);
|
||||
|
||||
RW(player->attack.applyWeaponEnchantment, send);
|
||||
RW(player->attack.applyProjectileEnchantment, send);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,17 @@ void PacketObjectSpawn::Object(WorldObject &worldObject, bool send)
|
|||
|
||||
if (worldObject.hasMaster)
|
||||
{
|
||||
RW(worldObject.master.refNumIndex, send);
|
||||
RW(worldObject.master.mpNum, send);
|
||||
RW(worldObject.master.guid, send);
|
||||
RW(worldObject.master.isPlayer, send);
|
||||
|
||||
if (worldObject.master.isPlayer)
|
||||
{
|
||||
RW(worldObject.master.guid, send);
|
||||
}
|
||||
else
|
||||
{
|
||||
RW(worldObject.master.refId, send, 1);
|
||||
RW(worldObject.master.refNumIndex, send);
|
||||
RW(worldObject.master.mpNum, send);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue