Skip to content

Commit

Permalink
Fixes crash due to formatting objHnd with :x
Browse files Browse the repository at this point in the history
  • Loading branch information
DudeMcDude committed Jun 10, 2016
1 parent 3199e5d commit e04aef0
Show file tree
Hide file tree
Showing 11 changed files with 371 additions and 26 deletions.
19 changes: 19 additions & 0 deletions TemplePlus/critter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,25 @@ int LegacyCritterSystem::GetSpellLvlCanCast(const objHndl& handle, SpellSourceTy
return 0;
}

int LegacyCritterSystem::GetSpellEnumsKnownByClass(const objHndl& handle, int spellClass, int* spellEnums, int capacity){
// todo: PrC extension
auto obj = gameSystems->GetObj().GetObject(handle);
auto spKnown = obj->GetSpellArray(obj_f_critter_spells_known_idx);
auto n = 0;
for (auto i = 0u; i < spKnown.GetSize(); i++){
auto &spData = spKnown[i];
if (spData.classCode == spellClass){
spellEnums[n++] = spData.spellEnum;
if (n >= capacity){
logger->warn("GetSpellEnumsKnown: Too many spells known! It's over 802!");
return n;
}

}
}
return n;
}

int LegacyCritterSystem::GetCritterNumNaturalAttacks(objHndl obj){
auto n = 0;

Expand Down
2 changes: 2 additions & 0 deletions TemplePlus/critter.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ struct LegacyCritterSystem : temple::AddressTable
int GetCritterAttackType(objHndl obj, int attackIdx);
int GetBaseAttackBonus(const objHndl& handle, Stat classBeingLeveld = Stat::stat_strength);
int GetSpellLvlCanCast(const objHndl& handle, SpellSourceType spellSourceType, SpellReadyingType spellReadyingType);
int GetSpellEnumsKnownByClass(const objHndl& handle, int spellClass, int* spellEnums, int capacity);

static int GetCritterNumNaturalAttacks(objHndl obj);
bool IsWarded(objHndl obj); // checks if creature is warded from melee attacks (by stuff like Meld Into Stone, Tree Shape, Otiluke's Resislient Sphere)
bool IsSummoned(objHndl obj);
Expand Down
46 changes: 34 additions & 12 deletions TemplePlus/d20_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,21 @@ class D20ClassHooks : public TempleFix
}
} d20ClassHooks;

bool D20ClassSystem::isNaturalCastingClass(Stat classEnum)
bool D20ClassSystem::IsNaturalCastingClass(Stat classEnum, objHndl handle)
{
if (classEnum == stat_level_bard || classEnum == stat_level_sorcerer) return 1;
if (classEnum == stat_level_bard || classEnum == stat_level_sorcerer)
return 1;
return 0;
}

bool D20ClassSystem::isNaturalCastingClass(uint32_t classEnum)
{
Stat castedClassEnum = static_cast<Stat>(classEnum);
if (classEnum == stat_level_bard || classEnum == stat_level_sorcerer) return 1;
return 0;
bool D20ClassSystem::IsNaturalCastingClass(uint32_t classEnum){
return IsNaturalCastingClass((Stat)classEnum);
}

bool D20ClassSystem::isVancianCastingClass(Stat classEnum)
bool D20ClassSystem::IsVancianCastingClass(Stat classEnum, objHndl handle )
{
if (classEnum == stat_level_cleric || classEnum == stat_level_druid || classEnum == stat_level_paladin || classEnum == stat_level_ranger || classEnum == stat_level_wizard) return 1;
if (classEnum == stat_level_cleric || classEnum == stat_level_druid || classEnum == stat_level_paladin || classEnum == stat_level_ranger || classEnum == stat_level_wizard)
return 1;
return 0;
}

Expand All @@ -93,9 +92,32 @@ bool D20ClassSystem::IsCastingClass(Stat classEnum)

bool D20ClassSystem::IsLateCastingClass(Stat classEnum)
{
if (classEnum == stat_level_paladin || classEnum == stat_level_ranger)
return 1;
return 0;
auto classSpec = classSpecs.find(classEnum);
if (classSpec == classSpecs.end())
return false;

if (classSpec->second.spellListType == SpellListType::Paladin
|| classSpec->second.spellListType == SpellListType::Ranger)
return true;

/*if (classEnum == stat_level_paladin || classEnum == stat_level_ranger)
return 1;*/
// todo: generalize for PrC's
return false;
}

bool D20ClassSystem::IsArcaneCastingClass(Stat classCode, objHndl handle){
auto classSpec = classSpecs.find(classCode);
if (classSpec == classSpecs.end())
return false;

if (classSpec->second.spellListType == SpellListType::Arcane
|| classSpec->second.spellListType == SpellListType::Bardic)
return true;

// todo handle PrC that can be either

return false;
}

bool D20ClassSystem::HasDomainSpells(Stat classEnum){
Expand Down
12 changes: 7 additions & 5 deletions TemplePlus/d20_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,20 @@ struct D20ClassSystem : temple::AddressTable
Stat vanillaClassEnums[VANILLA_NUM_CLASSES];
std::map<int, int> classEnums;
const int ClassLevelMax = 20;
static bool isNaturalCastingClass(Stat classEnum);
static bool isNaturalCastingClass(uint32_t classEnum);
static bool isVancianCastingClass(Stat classEnum);
static bool IsCastingClass(Stat classEnum);
static bool IsLateCastingClass(Stat classEnum); // for classes like Ranger / Paladin that start casting on level 4
bool IsNaturalCastingClass(Stat classEnum, objHndl handle = objHndl::null);
bool IsNaturalCastingClass(uint32_t classEnum);
bool IsVancianCastingClass(Stat classEnum, objHndl handle = objHndl::null);
bool IsCastingClass(Stat classEnum);
bool IsLateCastingClass(Stat classEnum); // for classes like Ranger / Paladin that start casting on level 4
bool IsArcaneCastingClass(Stat stat, objHndl handle = objHndl::null);
static bool HasDomainSpells(Stat classEnum);

void ClassPacketAlloc(ClassPacket *classPkt); // allocates the three IdxTables within ClassPacket
void ClassPacketDealloc(ClassPacket *classPkt);
uint32_t GetClassPacket(Stat classEnum, ClassPacket *classPkt); // fills the struct with content based on classEnum (e.g. Barbarian Feats in the featsIdxTable). Also STUB FOR PRESTIGE CLASSES! TODO
int GetBaseAttackBonus(Stat classCode, uint32_t classLvl); // gets the class's BAB
int GetSkillPts(Stat classEnum);


struct WildShapeSpec {
int protoId;
Expand Down
2 changes: 1 addition & 1 deletion TemplePlus/obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ void Objects::Destroy(objHndl ObjHnd) {
std::string name = this->GetDisplayName(ObjHnd, ObjHnd);
logger->info("Destroying {}", name);
if (destroyed.find(ObjHnd) != destroyed.end()) {
logger->error("Double destroying object {:x}", ObjHnd);
logger->error("Double destroying object {}", ObjHnd);
}
destroyed.insert(ObjHnd);

Expand Down
23 changes: 21 additions & 2 deletions TemplePlus/spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ bool SpellPacketBody::IsVancian(){
if (spellSys.isDomainSpell(spellClass))
return true;

if (d20ClassSys.isVancianCastingClass(spellSys.GetCastingClass(spellClass)))
if (d20ClassSys.IsVancianCastingClass(spellSys.GetCastingClass(spellClass)))
return true;

return false;
Expand Down Expand Up @@ -443,6 +443,14 @@ bool LegacySpellSystem::CheckAbilityScoreReqForSpell(objHndl handle, uint32_t sp
return temple::GetRef<BOOL(__cdecl)(objHndl, uint32_t, int)>(0x10075C60)(handle, spellEnum, statBeingRaised) != 0;
}

int LegacySpellSystem::GetSpellClass(int classEnum, bool isDomain){
if (isDomain){
return classEnum;
}

return 0x80 | classEnum;
}

const char* LegacySpellSystem::GetSpellEnumTAG(uint32_t spellEnum){

MesLine mesline;
Expand Down Expand Up @@ -1348,7 +1356,7 @@ uint32_t LegacySpellSystem::spellCanCast(objHndl objHnd, uint32_t spellEnum, uin
return 0;
}

if (d20ClassSys.isNaturalCastingClass(spellClassCode & 0x7F))
if (d20ClassSys.IsNaturalCastingClass(spellClassCode & 0x7F))
{
if (numSpellsKnownTooHigh(objHnd)) return 0;

Expand Down Expand Up @@ -1459,6 +1467,17 @@ bool LegacySpellSystem::IsSpellLike(int spellEnum){
&& spellEnum <= SPELL_LIKE_ABILITY_RANGE);
}

int LegacySpellSystem::GetSpellLevelBySpellClass(int spellEnum, int spellClass, objHndl handle){
SpellEntry spEntry(spellEnum);
for (auto i = 0u; i < spEntry.spellLvlsNum; i++){
if (spEntry.spellLvls[i].classCode == spellClass)
return spEntry.spellLvls[i].slotLevel;
}

//todo add PrC support
return -1;
}

uint32_t LegacySpellSystem::pickerArgsFromSpellEntry(SpellEntry* spellEntry, PickerArgs * pickArgs, objHndl objHnd, uint32_t casterLvl)
{
return _pickerArgsFromSpellEntry(spellEntry, pickArgs, objHnd, casterLvl);
Expand Down
4 changes: 3 additions & 1 deletion TemplePlus/spell.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ struct LegacySpellSystem : temple::AddressTable

const char* GetSpellMesline(uint32_t line) const;
bool CheckAbilityScoreReqForSpell(objHndl handle, uint32_t spellEnum, int statBeingRaised) const;

int GetSpellClass(int classEnum, bool isDomain = false);
static const char* GetSpellEnumTAG(uint32_t spellEnum);
const char* GetSpellName(uint32_t spellEnum) const;

Expand Down Expand Up @@ -194,6 +194,8 @@ struct LegacySpellSystem : temple::AddressTable
bool IsArcaneSpellClass(uint32_t spellClass);

static bool IsSpellLike(int spellEnum); // checks if the spell is in the Spell Like Ability range
int GetSpellLevelBySpellClass(int spellEnum, int spellClass, objHndl handle = objHndl::null);


uint32_t pickerArgsFromSpellEntry(SpellEntry * spellEntry, PickerArgs * pickArgs, objHndl objHnd, uint32_t casterLevel);
uint32_t GetSpellRangeExact(SpellRangeType spellRangeType, uint32_t casterLevel, objHndl caster);
Expand Down
3 changes: 3 additions & 0 deletions TemplePlus/spell_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const uint32_t SPELL_ENUM_MAX_EXPANDED = 3999;
#define NUM_SPELL_LEVELS 10 // spells are levels 0-9
#define MAX_SPELL_TARGETS 32
#define INV_IDX_INVALID 255 // indicates that a spell is not an item spell
#define SPELL_ENUM_LABEL_START 803 // the range of 803-812 is reserved for "spell labels" in the chargen / levelup spell UI
#define SPELL_ENUM_VACANT 802 // used for vacant spellbook slots
#define SPELL_ENUM_NEW_SLOT_START 1605 // for bard/sorc new spells; range is in 1605-1614

enum SpellStoreType : uint8_t{
spellStoreNone = 0,
Expand Down
4 changes: 2 additions & 2 deletions TemplePlus/ui/ui_char.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ void CharUiSystem::SpellsShow(objHndl obj)
// show the first class's spellbook / spells memorized
if (uiCharSpellTabsCount > 0 && !spellSys.isDomainSpell(navClassPackets[0].spellClassCode)) {
auto classCode = spellSys.GetCastingClass(navClassPackets[0].spellClassCode );
if (d20ClassSys.isVancianCastingClass(classCode)){
if (d20ClassSys.IsVancianCastingClass(classCode)){
ui.WidgetSetHidden(charSpellPackets[0].classMemorizeWnd->widgetId, 0);
}
ui.WidgetSetHidden(charSpellPackets[0].classSpellbookWnd->widgetId, 0);
Expand Down Expand Up @@ -553,7 +553,7 @@ void CharUiSystem::SpellsShow(objHndl obj)
auto spellClassCode = navClassPackets[uiCharSpellsNavClassTabIdx].spellClassCode;
if (!spellSys.isDomainSpell(spellClassCode)){
auto casterClassCode = spellSys.GetCastingClass(spellClassCode);
if (d20ClassSys.isNaturalCastingClass(casterClassCode))
if (d20ClassSys.IsNaturalCastingClass(casterClassCode))
showMemSpells = false;
}

Expand Down
Loading

0 comments on commit e04aef0

Please sign in to comment.