mirror of
https://gitlab.com/Scribble/gdlenhanced.git
synced 2026-08-17 14:23:04 -04:00
210 lines
6 KiB
C++
210 lines
6 KiB
C++
|
|
#include "StdAfx.h"
|
|
#include "WeenieObject.h"
|
|
#include "Healer.h"
|
|
#include "Player.h"
|
|
|
|
CHealerWeenie::CHealerWeenie()
|
|
{
|
|
SetName("Healer");
|
|
m_Qualities.m_WeenieType = Healer_WeenieType;
|
|
}
|
|
|
|
CHealerWeenie::~CHealerWeenie()
|
|
{
|
|
}
|
|
|
|
void CHealerWeenie::ApplyQualityOverrides()
|
|
{
|
|
}
|
|
|
|
int CHealerWeenie::UseWith(std::shared_ptr<CPlayerWeenie> player, std::shared_ptr<CWeenieObject> with)
|
|
{
|
|
DWORD healing_skill = 0;
|
|
if (!player->InqSkill(HEALING_SKILL, healing_skill, TRUE) || !healing_skill)
|
|
{
|
|
player->NotifyWeenieError(WERROR_HEAL_NOT_TRAINED);
|
|
player->NotifyUseDone(0);
|
|
return WERROR_NONE;
|
|
}
|
|
|
|
CHealerUseEvent *useEvent = new CHealerUseEvent;
|
|
useEvent->_target_id = with->GetID();
|
|
useEvent->_tool_id = GetID();
|
|
useEvent->_max_use_distance = 1.0;
|
|
player->ExecuteUseEvent(useEvent);
|
|
|
|
return WERROR_NONE;
|
|
}
|
|
|
|
void CHealerUseEvent::OnReadyToUse()
|
|
{
|
|
std::shared_ptr<CWeenieObject> pWeenie = _weenie.lock();
|
|
if (!pWeenie)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_target_id == pWeenie->GetID())
|
|
{
|
|
ExecuteUseAnimation(Motion_SkillHealSelf);
|
|
}
|
|
else
|
|
{
|
|
// TODO find the right animation for healing another player - using Woah animation now, seems right.
|
|
ExecuteUseAnimation(Motion_Woah);
|
|
}
|
|
}
|
|
|
|
void CHealerUseEvent::OnUseAnimSuccess(DWORD motion)
|
|
{
|
|
std::shared_ptr<CWeenieObject> pWeenie = _weenie.lock();
|
|
if (!pWeenie)
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::shared_ptr<CWeenieObject> target = GetTarget();
|
|
std::shared_ptr<CWeenieObject> tool = GetTool();
|
|
|
|
if (tool && target && !target->IsDead() && !target->IsInPortalSpace())
|
|
{
|
|
int amountHealed = 0;
|
|
int usesLeft = tool->InqIntQuality(STRUCTURE_INT, -1);
|
|
|
|
if (usesLeft != 0)
|
|
{
|
|
if (usesLeft > 0)
|
|
usesLeft--;
|
|
|
|
const char *prefix = "";
|
|
const char *vitalName = "";
|
|
|
|
DWORD boost_stat = tool->InqIntQuality(BOOSTER_ENUM_INT, 0);
|
|
DWORD boost_value = tool->InqIntQuality(BOOST_VALUE_INT, 0);
|
|
bool success = false;
|
|
|
|
switch (boost_stat)
|
|
{
|
|
case HEALTH_ATTRIBUTE_2ND:
|
|
case STAMINA_ATTRIBUTE_2ND:
|
|
case MANA_ATTRIBUTE_2ND:
|
|
{
|
|
STypeAttribute2nd maxStatType = (STypeAttribute2nd)(boost_stat - 1);
|
|
STypeAttribute2nd statType = (STypeAttribute2nd)boost_stat;
|
|
|
|
DWORD statValue = 0, maxStatValue = 0;
|
|
target->m_Qualities.InqAttribute2nd(statType, statValue, FALSE);
|
|
target->m_Qualities.InqAttribute2nd(maxStatType, maxStatValue, FALSE);
|
|
|
|
int missingVital = max(0, (int)maxStatValue - (int)statValue);
|
|
int difficulty = max(0, (missingVital * 2) - tool->InqIntQuality(BOOST_VALUE_INT, 0));
|
|
|
|
DWORD healing_skill = 0;
|
|
pWeenie->InqSkill(HEALING_SKILL, healing_skill, FALSE);
|
|
|
|
// this is wrong, but whatever we'll fake it
|
|
DWORD heal_min = (int)(healing_skill * 0.2) * tool->InqFloatQuality(HEALKIT_MOD_FLOAT, 1.0);
|
|
DWORD heal_max = (int)(healing_skill * 0.5) * tool->InqFloatQuality(HEALKIT_MOD_FLOAT, 1.0);
|
|
|
|
amountHealed = Random::GenInt(heal_min, heal_max);
|
|
if (amountHealed > missingVital)
|
|
amountHealed = missingVital;
|
|
|
|
int staminaNecessary = amountHealed / 5; //1 point of stamina used for every 5 health healed.
|
|
|
|
if (pWeenie->GetStamina() < staminaNecessary)
|
|
{
|
|
//can't heal if there's not enough stamina
|
|
pWeenie->NotifyWeenieError(WERROR_STAMINA_TOO_LOW);
|
|
Cancel();
|
|
return;
|
|
}
|
|
pWeenie->AdjustStamina(-staminaNecessary);
|
|
|
|
success = Random::RollDice(0.0, 1.0) <= GetSkillChance(healing_skill, difficulty);
|
|
if (success)
|
|
{
|
|
if (amountHealed > (int)(heal_max * 0.8))
|
|
prefix = "expertly ";
|
|
|
|
DWORD newStatValue = min(statValue + amountHealed, maxStatValue);
|
|
|
|
int statChange = newStatValue - statValue;
|
|
if (statChange)
|
|
{
|
|
if (target->AsPlayer() && statType == HEALTH_ATTRIBUTE_2ND)
|
|
{
|
|
target->AdjustHealth(statChange);
|
|
target->NotifyAttribute2ndStatUpdated(statType);
|
|
}
|
|
else
|
|
{
|
|
target->m_Qualities.SetAttribute2nd(statType, newStatValue);
|
|
target->NotifyAttribute2ndStatUpdated(statType);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
switch (boost_stat)
|
|
{
|
|
case HEALTH_ATTRIBUTE_2ND: vitalName = "Health"; break;
|
|
case STAMINA_ATTRIBUTE_2ND: vitalName = "Stamina"; break;
|
|
case MANA_ATTRIBUTE_2ND: vitalName = "Mana"; break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
amountHealed = max(0, amountHealed);
|
|
|
|
// heal up
|
|
if (success)
|
|
{
|
|
if (_target_id == pWeenie->GetID())
|
|
{
|
|
if (usesLeft >= 0)
|
|
pWeenie->SendText(csprintf("You %sheal yourself for %d %s points. Your %s has %u uses left.", prefix, amountHealed, vitalName, tool->GetName().c_str(), usesLeft), LTT_DEFAULT);
|
|
else
|
|
pWeenie->SendText(csprintf("You %sheal yourself for %d %s points with %s.", prefix, amountHealed, vitalName, tool->GetName().c_str()), LTT_DEFAULT);
|
|
}
|
|
else
|
|
{
|
|
if (usesLeft >= 0)
|
|
pWeenie->SendText(csprintf("You %sheal %s for %d %s points. Your %s has %u uses left.", prefix, target->GetName().c_str(), amountHealed, vitalName, tool->GetName().c_str(), usesLeft), LTT_DEFAULT);
|
|
else
|
|
pWeenie->SendText(csprintf("You %sheal %s for %d %s points with %s.", prefix, target->GetName().c_str(), amountHealed, vitalName, tool->GetName().c_str()), LTT_DEFAULT);
|
|
|
|
target->SendText(csprintf("%s heals you for %d %s points.", pWeenie->GetName().c_str(), amountHealed, vitalName), LTT_DEFAULT);
|
|
}
|
|
|
|
if (boost_stat == HEALTH_ATTRIBUTE_2ND)
|
|
{
|
|
if (std::shared_ptr<CPlayerWeenie> pPlayer = pWeenie->AsPlayer())
|
|
{
|
|
// update the target's health on the healing player asap
|
|
pPlayer->RefreshTargetHealth();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_target_id == pWeenie->GetID())
|
|
{
|
|
pWeenie->SendText(csprintf("You fail to heal yourself. Your %s has %d uses left.", tool->GetName().c_str(), usesLeft), LTT_DEFAULT);
|
|
}
|
|
else
|
|
{
|
|
pWeenie->SendText(csprintf("You fail to heal %s. Your %s has %d uses left.", target->GetName().c_str(), tool->GetName().c_str(), usesLeft), LTT_DEFAULT);
|
|
target->SendText(csprintf("%s fails to heal you.", pWeenie->GetName().c_str()), LTT_DEFAULT);
|
|
}
|
|
}
|
|
|
|
tool->DecrementStackOrStructureNum(true);
|
|
}
|
|
}
|
|
|
|
Done();
|
|
}
|