mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-26 09:35:28 +00:00
Only allow using powers once every 24 h. Apply on touch effects.
This commit is contained in:
parent
71828351e6
commit
6cd373c5c6
@ -273,7 +273,7 @@ void MWMechanics::Alchemy::addPotion (const std::string& name)
|
|||||||
|
|
||||||
newRecord.mName = name;
|
newRecord.mName = name;
|
||||||
|
|
||||||
int index = static_cast<int> (std::rand()/static_cast<double> (RAND_MAX+1)*6);
|
int index = static_cast<int> (std::rand()/(static_cast<double> (RAND_MAX)+1)*6);
|
||||||
assert (index>=0 && index<6);
|
assert (index>=0 && index<6);
|
||||||
|
|
||||||
static const char *name[] = { "standard", "bargain", "cheap", "fresh", "exclusive", "quality" };
|
static const char *name[] = { "standard", "bargain", "cheap", "fresh", "exclusive", "quality" };
|
||||||
|
@ -342,4 +342,18 @@ namespace MWMechanics
|
|||||||
{
|
{
|
||||||
return mLastHitObject;
|
return mLastHitObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CreatureStats::canUsePower(const std::string &power)
|
||||||
|
{
|
||||||
|
std::map<std::string, MWWorld::TimeStamp>::iterator it = mUsedPowers.find(power);
|
||||||
|
if (it == mUsedPowers.end() || it->second + 24 <= MWBase::Environment::get().getWorld()->getTimeStamp())
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreatureStats::usePower(const std::string &power)
|
||||||
|
{
|
||||||
|
mUsedPowers[power] = MWBase::Environment::get().getWorld()->getTimeStamp();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,8 @@ namespace MWMechanics
|
|||||||
|
|
||||||
std::string mLastHitObject; // The last object to hit this actor
|
std::string mLastHitObject; // The last object to hit this actor
|
||||||
|
|
||||||
|
std::map<std::string, MWWorld::TimeStamp> mUsedPowers;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool mIsWerewolf;
|
bool mIsWerewolf;
|
||||||
Stat<int> mWerewolfAttributes[8];
|
Stat<int> mWerewolfAttributes[8];
|
||||||
@ -47,6 +49,9 @@ namespace MWMechanics
|
|||||||
public:
|
public:
|
||||||
CreatureStats();
|
CreatureStats();
|
||||||
|
|
||||||
|
bool canUsePower (const std::string& power);
|
||||||
|
void usePower (const std::string& power);
|
||||||
|
|
||||||
const Stat<int> & getAttribute(int index) const;
|
const Stat<int> & getAttribute(int index) const;
|
||||||
|
|
||||||
const DynamicStat<float> & getHealth() const;
|
const DynamicStat<float> & getHealth() const;
|
||||||
|
@ -1991,6 +1991,7 @@ namespace MWWorld
|
|||||||
stats.setAttackingOrSpell(false);
|
stats.setAttackingOrSpell(false);
|
||||||
|
|
||||||
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
||||||
|
std::string sourceName = "";
|
||||||
if (!selectedSpell.empty())
|
if (!selectedSpell.empty())
|
||||||
{
|
{
|
||||||
const ESM::Spell* spell = getStore().get<ESM::Spell>().search(selectedSpell);
|
const ESM::Spell* spell = getStore().get<ESM::Spell>().search(selectedSpell);
|
||||||
@ -2011,6 +2012,18 @@ namespace MWWorld
|
|||||||
stats.setMagicka(magicka);
|
stats.setMagicka(magicka);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is a power, check if it was already used in last 24h
|
||||||
|
if (!fail && spell->mData.mType & ESM::Spell::ST_Power)
|
||||||
|
{
|
||||||
|
if (stats.canUsePower(selectedSpell))
|
||||||
|
stats.usePower(selectedSpell);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sPowerAlreadyUsed}");
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check success
|
// Check success
|
||||||
int successChance = MWMechanics::getSpellSuccessChance(selectedSpell, actor);
|
int successChance = MWMechanics::getSpellSuccessChance(selectedSpell, actor);
|
||||||
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
int roll = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
|
||||||
@ -2042,18 +2055,13 @@ namespace MWWorld
|
|||||||
|
|
||||||
actor.getClass().skillUsageSucceeded(actor, MWMechanics::spellSchoolToSkill(MWMechanics::getSpellSchool(selectedSpell, actor)), 0);
|
actor.getClass().skillUsageSucceeded(actor, MWMechanics::spellSchoolToSkill(MWMechanics::getSpellSchool(selectedSpell, actor)), 0);
|
||||||
|
|
||||||
actor.getClass().getCreatureStats(actor).getActiveSpells().addSpell(selectedSpell, actor, ESM::RT_Self);
|
|
||||||
// TODO: RT_Range, RT_Touch
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryStore& inv = actor.getClass().getInventoryStore(actor);
|
InventoryStore& inv = actor.getClass().getInventoryStore(actor);
|
||||||
if (inv.getSelectedEnchantItem() != inv.end())
|
if (selectedSpell.empty() && inv.getSelectedEnchantItem() != inv.end())
|
||||||
{
|
{
|
||||||
MWWorld::Ptr item = *inv.getSelectedEnchantItem();
|
MWWorld::Ptr item = *inv.getSelectedEnchantItem();
|
||||||
std::string id = item.getClass().getEnchantment(item);
|
selectedSpell = item.getClass().getEnchantment(item);
|
||||||
const ESM::Enchantment* enchantment = getStore().get<ESM::Enchantment>().search (id);
|
const ESM::Enchantment* enchantment = getStore().get<ESM::Enchantment>().search (selectedSpell);
|
||||||
|
|
||||||
|
|
||||||
if (enchantment->mData.mType == ESM::Enchantment::WhenUsed)
|
if (enchantment->mData.mType == ESM::Enchantment::WhenUsed)
|
||||||
{
|
{
|
||||||
@ -2080,8 +2088,7 @@ namespace MWWorld
|
|||||||
item.getRefData().setCount(item.getRefData().getCount()-1);
|
item.getRefData().setCount(item.getRefData().getCount()-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string itemName = item.getClass().getName(item);
|
sourceName = item.getClass().getName(item);
|
||||||
actor.getClass().getCreatureStats(actor).getActiveSpells().addSpell(id, actor, ESM::RT_Self, itemName);
|
|
||||||
|
|
||||||
if (!item.getRefData().getCount())
|
if (!item.getRefData().getCount())
|
||||||
{
|
{
|
||||||
@ -2091,10 +2098,28 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item); // Set again to show the modified charge
|
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(item); // Set again to show the modified charge
|
||||||
|
|
||||||
|
|
||||||
// TODO: RT_Range, RT_Touch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now apply the spell!
|
||||||
|
|
||||||
|
// Apply Self portion
|
||||||
|
actor.getClass().getCreatureStats(actor).getActiveSpells().addSpell(selectedSpell, actor, ESM::RT_Self, sourceName);
|
||||||
|
|
||||||
|
// Apply Touch portion
|
||||||
|
// TODO: Distance is probably incorrect, and should it be hardcoded?
|
||||||
|
std::pair<MWWorld::Ptr, Ogre::Vector3> contact = getHitContact(actor, 100);
|
||||||
|
if (!contact.first.isEmpty())
|
||||||
|
{
|
||||||
|
if (contact.first.getClass().isActor())
|
||||||
|
contact.first.getClass().getCreatureStats(contact.first).getActiveSpells().addSpell(selectedSpell, contact.first, ESM::RT_Touch, sourceName);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We hit a non-actor, e.g. a door. Only instant effects are relevant.
|
||||||
|
// inflictSpellOnNonActor(contact.first, selectedSpell, ESM::RT_Touch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Launch projectile if there's a Target portion
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user