Implement magic

This commit is contained in:
Koncord 2016-11-12 19:39:04 +08:00
parent 729da2c0ba
commit 56959ebfda
10 changed files with 41 additions and 38 deletions

View file

@ -606,7 +606,7 @@ namespace MWClass
if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr()) if (ptr == MWBase::Environment::get().getWorld()->getPlayerPtr())
{ {
mwmp::Main::get().getLocalPlayer()->GetAttack()->success = false; mwmp::Main::get().getLocalPlayer()->GetAttack()->success = false;
mwmp::Main::get().getLocalPlayer()->sendAttack(0); mwmp::Main::get().getLocalPlayer()->sendAttack(mwmp::Attack::MELEE);
} }
othercls.onHit(victim, 0.0f, false, weapon, ptr, osg::Vec3f(), false); othercls.onHit(victim, 0.0f, false, weapon, ptr, osg::Vec3f(), false);
@ -850,7 +850,7 @@ namespace MWClass
_atk->attacker = mwmp::Main::get().getLocalPlayer()->guid; _atk->attacker = mwmp::Main::get().getLocalPlayer()->guid;
_atk->target = mwmp::Players::GetPlayer(ptr)->guid; _atk->target = mwmp::Players::GetPlayer(ptr)->guid;
_atk->knockdown = getCreatureStats(ptr).getKnockedDown(); _atk->knockdown = getCreatureStats(ptr).getKnockedDown();
mwmp::Main::get().getLocalPlayer()->sendAttack(0); // todo: make this sensitive to different weapon types mwmp::Main::get().getLocalPlayer()->sendAttack(mwmp::Attack::MELEE); // todo: make this sensitive to different weapon types
} }
if (ptr == MWMechanics::getPlayer()) if (ptr == MWMechanics::getPlayer())

View file

@ -1035,12 +1035,15 @@ namespace MWMechanics
if (iter->first == player) if (iter->first == player)
{ {
bool state = MWBase::Environment::get().getWorld()->getPlayer().getAttackingOrSpell(); bool state = MWBase::Environment::get().getWorld()->getPlayer().getAttackingOrSpell();
DrawState_ dstate = player.getClass().getNpcStats(player).getDrawState();
iter->second->getCharacterController()->setAttackingOrSpell(state); iter->second->getCharacterController()->setAttackingOrSpell(state);
mwmp::Main::get().getLocalPlayer()->prepareAttack(2, state); if (dstate == DrawState_Weapon)
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MELEE, state);
} }
if (mwmp::Main::get().getNetworking()->isDedicatedPlayer(iter->first)) mwmp::DedicatedPlayer *dedicatedPlayer = mwmp::Players::GetPlayer(iter->first);
iter->second->getCharacterController()->setAttackingOrSpell(mwmp::Main::get().getNetworking()->Attack(iter->first)); if (dedicatedPlayer != nullptr)
dedicatedPlayer->updateActor(iter->second);
if (!iter->first.getClass().getCreatureStats(iter->first).isDead()) if (!iter->first.getClass().getCreatureStats(iter->first).isDead())

View file

@ -26,6 +26,7 @@
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/sceneutil/positionattitudetransform.hpp> #include <components/sceneutil/positionattitudetransform.hpp>
#include <apps/openmw/mwmp/Main.hpp>
#include "../mwrender/animation.hpp" #include "../mwrender/animation.hpp"
@ -1233,6 +1234,9 @@ bool CharacterController::updateWeaponState()
if(!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr)) if(!spellid.empty() && MWBase::Environment::get().getWorld()->startSpellCast(mPtr))
{ {
if (mPtr == getPlayer())
mwmp::Main::get().getLocalPlayer()->prepareAttack(mwmp::Attack::MAGIC, true);
MWMechanics::CastSpell cast(mPtr, NULL); MWMechanics::CastSpell cast(mPtr, NULL);
cast.playSpellCastingEffects(spellid); cast.playSpellCastingEffects(spellid);

View file

@ -799,35 +799,19 @@ namespace MWMechanics
bool isDedicated = mwmp::Main::get().getNetworking()->isDedicatedPlayer(mCaster); bool isDedicated = mwmp::Main::get().getNetworking()->isDedicatedPlayer(mCaster);
if (mCaster == getPlayer())
{
mwmp::Main::get().getLocalPlayer()->GetAttack()->success = true;
mwmp::Main::get().getLocalPlayer()->GetAttack()->pressed = true;
}
if (isDedicated) if (isDedicated)
{
mwmp::Players::GetPlayer(mCaster)->GetAttack()->pressed = false; mwmp::Players::GetPlayer(mCaster)->GetAttack()->pressed = false;
}
if ((!isDedicated && Misc::Rng::roll0to99() >= successChance) || if ((!isDedicated && !mwmp::Main::get().getLocalPlayer()->GetAttack()->success) ||
(isDedicated && mwmp::Players::GetPlayer(mCaster)->GetAttack()->success == 0)) (isDedicated && mwmp::Players::GetPlayer(mCaster)->GetAttack()->success == 0))
{ {
if (mCaster == getPlayer()) if (mCaster == getPlayer())
{ {
mwmp::Main::get().getLocalPlayer()->GetAttack()->success = false;
MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicSkillFail}"); MWBase::Environment::get().getWindowManager()->messageBox("#{sMagicSkillFail}");
} }
fail = true; fail = true;
} }
if (mCaster == getPlayer())
{
mwmp::Main::get().getLocalPlayer()->sendAttack(1);
mwmp::Main::get().getLocalPlayer()->GetAttack()->pressed = false;
mwmp::Main::get().getLocalPlayer()->sendAttack(1);
}
if (fail) if (fail)
{ {
// Failure sound // Failure sound

View file

@ -12,6 +12,7 @@
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/customdata.hpp" #include "../mwworld/customdata.hpp"
#include "../mwclass/npc.hpp" #include "../mwclass/npc.hpp"
#include "../mwmechanics/actor.hpp"
#include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
#include "../mwmechanics/mechanicsmanagerimp.hpp" #include "../mwmechanics/mechanicsmanagerimp.hpp"
@ -500,3 +501,8 @@ void DedicatedPlayer::setMarkerState(bool state)
else else
removeMarker(); removeMarker();
} }
void DedicatedPlayer::updateActor(MWMechanics::Actor *actor)
{
actor->getCharacterController()->setAttackingOrSpell(GetAttack()->pressed);
}

View file

@ -14,6 +14,10 @@
#include <components/openmw-mp/Base/BasePlayer.hpp> #include <components/openmw-mp/Base/BasePlayer.hpp>
#include <components/esm/custommarkerstate.hpp> #include <components/esm/custommarkerstate.hpp>
namespace MWMechanics
{
class Actor;
}
namespace mwmp namespace mwmp
{ {
@ -50,6 +54,7 @@ namespace mwmp
void updateMarker(); void updateMarker();
void removeMarker(); void removeMarker();
void setMarkerState(bool state); void setMarkerState(bool state);
void updateActor(MWMechanics::Actor *actor);
private: private:
DedicatedPlayer(RakNet::RakNetGUID guid); DedicatedPlayer(RakNet::RakNetGUID guid);
virtual ~DedicatedPlayer(); virtual ~DedicatedPlayer();

View file

@ -23,6 +23,7 @@
#include <apps/openmw/mwmechanics/spellcasting.hpp> #include <apps/openmw/mwmechanics/spellcasting.hpp>
#include <apps/openmw/mwgui/inventorywindow.hpp> #include <apps/openmw/mwgui/inventorywindow.hpp>
#include <components/openmw-mp/Log.hpp> #include <components/openmw-mp/Log.hpp>
#include <components/misc/rng.hpp>
#include "LocalPlayer.hpp" #include "LocalPlayer.hpp"
#include "Main.hpp" #include "Main.hpp"
@ -510,7 +511,7 @@ void LocalPlayer::updateAttackState(bool forceUpdate)
const string &spell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); const string &spell = MWBase::Environment::get().getWindowManager()->getSelectedSpell();
GetAttack()->attacker = guid; GetAttack()->attacker = guid;
GetAttack()->type = 1; GetAttack()->type = Attack::MAGIC;
GetAttack()->pressed = true; GetAttack()->pressed = true;
GetAttack()->refid = spell; GetAttack()->refid = spell;
@ -793,18 +794,11 @@ void LocalPlayer::sendClass()
GetNetworking()->GetPlayerPacket(ID_GAME_CHARCLASS)->Send(this); GetNetworking()->GetPlayerPacket(ID_GAME_CHARCLASS)->Send(this);
} }
void LocalPlayer::sendAttack(char type) void LocalPlayer::sendAttack(Attack::TYPE type)
{ {
MWMechanics::DrawState_ state = GetPlayerPtr().getClass().getNpcStats(GetPlayerPtr()).getDrawState(); MWMechanics::DrawState_ state = GetPlayerPtr().getClass().getNpcStats(GetPlayerPtr()).getDrawState();
if (state == MWMechanics::DrawState_Spell)
{
}
else
{
}
GetAttack()->type = type; GetAttack()->type = type;
GetAttack()->pressed = false; GetAttack()->pressed = false;
RakNet::BitStream bs; RakNet::BitStream bs;
@ -812,9 +806,9 @@ void LocalPlayer::sendAttack(char type)
GetNetworking()->SendData(&bs); GetNetworking()->SendData(&bs);
} }
void LocalPlayer::prepareAttack(char type, bool state) void LocalPlayer::prepareAttack(Attack::TYPE type, bool state)
{ {
if (GetAttack()->pressed == state) if (GetAttack()->pressed == state && type != Attack::MAGIC)
return; return;
MWMechanics::DrawState_ dstate = GetPlayerPtr().getClass().getNpcStats(GetPlayerPtr()).getDrawState(); MWMechanics::DrawState_ dstate = GetPlayerPtr().getClass().getNpcStats(GetPlayerPtr()).getDrawState();
@ -822,18 +816,18 @@ void LocalPlayer::prepareAttack(char type, bool state)
if (dstate == MWMechanics::DrawState_Spell) if (dstate == MWMechanics::DrawState_Spell)
{ {
const string &spell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); const string &spell = MWBase::Environment::get().getWindowManager()->getSelectedSpell();
GetAttack()->success = Misc::Rng::roll0to99() >=MWMechanics::getSpellSuccessChance(spell, GetPlayerPtr());
state = true;
GetAttack()->refid = spell; GetAttack()->refid = spell;
} }
else else
{ {
GetAttack()->success = false;
} }
GetAttack()->pressed = state; GetAttack()->pressed = state;
GetAttack()->type = type; GetAttack()->type = type;
GetAttack()->knockdown = false; GetAttack()->knockdown = false;
GetAttack()->success = false;
GetAttack()->block = false; GetAttack()->block = false;
GetAttack()->target = RakNet::RakNetGUID(); GetAttack()->target = RakNet::RakNetGUID();
GetAttack()->attacker = guid; GetAttack()->attacker = guid;

View file

@ -46,9 +46,9 @@ namespace mwmp
void setInventory(); void setInventory();
void sendClass(); void sendClass();
void sendAttack(char type); void sendAttack(Attack::TYPE type);
void prepareAttack(char type, bool state); void prepareAttack(Attack::TYPE type, bool state);

View file

@ -397,6 +397,7 @@ void Networking::ProcessPlayerPacket(RakNet::Packet *packet)
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "SpellId: %s", LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "SpellId: %s",
pl->GetAttack()->refid.c_str()); pl->GetAttack()->refid.c_str());
LOG_APPEND(Log::LOG_VERBOSE, " - success: %d", pl->GetAttack()->success);
} }
} }
break; break;

View file

@ -20,6 +20,12 @@ namespace mwmp
RakNet::RakNetGUID target; RakNet::RakNetGUID target;
RakNet::RakNetGUID attacker; RakNet::RakNetGUID attacker;
char type; // 0 - melee, 1 - magic, 2 - throwable char type; // 0 - melee, 1 - magic, 2 - throwable
enum TYPE
{
MELEE = 0,
MAGIC,
THROWABLE
};
std::string refid; // id of spell (e.g. "fireball") std::string refid; // id of spell (e.g. "fireball")
char success; char success;
char block; char block;