Skip to content

Commit

Permalink
generic skill cost
Browse files Browse the repository at this point in the history
  • Loading branch information
malytomas committed Aug 4, 2023
1 parent eabfce1 commit 16a7cb9
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 52 deletions.
29 changes: 11 additions & 18 deletions sources/dnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ enum class AttributeEnum : uint8
Scalar,
};

using AttributesValueMappingInt = std::map<AttributeEnum, sint32>;
using AttributesValueMappingFloat = std::map<AttributeEnum, Real>;

enum class DamageTypeEnum : uint8
{
None,
Expand All @@ -89,31 +86,27 @@ enum class SkillTargetEnum : uint8
Item,
};

struct SkillCost
{
uint32 life = 0;
uint32 mana = 0;
uint32 stamina = 0;
};

using SkillAttributesEffects = std::map<AttributeEnum, AttributesValueMappingFloat>;
using AttributesValuesList = std::map<AttributeEnum, sint32>;
using AttributesEquationFactors = std::map<AttributeEnum, Real>;
using SkillAttributes = std::map<AttributeEnum, AttributesEquationFactors>;

constexpr const char *Alone = "\"alone\""; // requires that the caster is alone (no other creature (player or monster) are visible in 15 range)
constexpr const char *LineOfSight = "\"lineOfSight\""; // requires the target position is visible from the caster position
constexpr const char *Moves = "\"moves\""; // moves the caster to the target position, or the target to the caster position
constexpr const char *Knockback = "\"knockback\""; // moves the caster/target one tile away from the other
constexpr const char *Stun = "\"stun\""; // prevents the caster/target from performing any actions for one tick, and grants immunity to stun for the following tick
constexpr const char *GroundEffect = "\"groundEffect\""; // creates ground effect at caster/target position, which applies the effects of the skill
constexpr const char *Passive = "\"passive\""; // the effects of the skill are automatically applied every tick, assuming the cost can be paid; multiple passive skills are allowed

struct Skill : public Thing
{
String name = "unnamed skill";
detail::StringBase<30> icon = "skill";
SkillTargetEnum target = SkillTargetEnum::None;
SkillCost cost;
AttributesValueMappingFloat range, radius, duration, damageAmount;
AttributesValuesList cost;
AttributesEquationFactors range, radius, duration, damageAmount;
DamageTypeEnum damageType = DamageTypeEnum::None;
SkillAttributesEffects casterAttributes, targetAttributes;
SkillAttributes casterAttributes, targetAttributes;
std::vector<std::string> casterFlags, targetFlags;
};

Expand All @@ -133,8 +126,8 @@ struct Item : public Thing
String name = "unnamed item";
detail::StringBase<30> icon = "item";
SlotEnum slot = SlotEnum::None;
AttributesValueMappingInt requirements;
AttributesValueMappingInt attributes;
AttributesValuesList requirements;
AttributesValuesList attributes;
std::vector<Skill> skills;
std::vector<std::string> flags;
uint32 buyPrice = 0;
Expand All @@ -146,7 +139,7 @@ struct Monster : public Thing
detail::StringBase<30> icon = "monster";
detail::StringBase<30> algorithm = "default";
detail::StringBase<30> faction = "monster";
AttributesValueMappingInt attributes;
AttributesValuesList attributes;
std::vector<Item> equippedItems;
std::vector<Variant> onDeath;
uint32 score = 0;
Expand Down Expand Up @@ -240,7 +233,7 @@ struct Generate
Real support = Real::Nan(); // 0 = combat, 1 = support

Generate() = default;
explicit Generate(uint32 level, sint32 powerOffset = 0, SlotEnum slot = SlotEnum::None);
explicit Generate(uint32 level, sint32 powerOffset, SlotEnum slot = SlotEnum::None);
void randomize();
bool valid() const;
sint32 powerOffset() const;
Expand Down
4 changes: 2 additions & 2 deletions sources/exportFloor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ void exportExamples(uint32 maxLevel)
Holder<File> json = writeFile("items.json");
for (uint32 i = 1; i < maxLevel; i++)
{
json->write(exportItem(generateItem(Generate(i))));
json->write(exportItem(generateItem(Generate(i, 0))));
json->writeLine("");
json->writeLine("");
}
Expand All @@ -289,7 +289,7 @@ void exportExamples(uint32 maxLevel)
Holder<File> json = writeFile("monsters.json");
for (uint32 i = 1; i < maxLevel; i++)
{
json->write(exportMonster(generateMonster(Generate(i))));
json->write(exportMonster(generateMonster(Generate(i, 0))));
json->writeLine("");
json->writeLine("");
}
Expand Down
23 changes: 5 additions & 18 deletions sources/exportThing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ namespace
}

template<class AttributesValueMapping>
requires(std::is_same_v<AttributesValueMapping, AttributesValueMappingInt> || std::is_same_v<AttributesValueMapping, AttributesValueMappingFloat>)
requires(std::is_same_v<AttributesValueMapping, AttributesValuesList> || std::is_same_v<AttributesValueMapping, AttributesEquationFactors>)
std::string attributesValueMappingJson(const AttributesValueMapping &attributesValues)
{
std::string r;
Expand Down Expand Up @@ -111,20 +111,7 @@ namespace
}
}

std::string skillCostJson(const SkillCost &cost)
{
std::string r;
if (cost.life != 0)
r += (Stringizer() + "\"life\":" + cost.life + ",").value.c_str();
if (cost.mana != 0)
r += (Stringizer() + "\"mana\":" + cost.mana + ",").value.c_str();
if (cost.stamina != 0)
r += (Stringizer() + "\"stamina\":" + cost.stamina + ",").value.c_str();
removeLastComma(r);
return "{" + r + "}";
}

std::string skillAttributesEffectsJson(const SkillAttributesEffects &effects)
std::string skillAttributesJson(const SkillAttributes &effects)
{
std::string r;
for (const auto &it : effects)
Expand Down Expand Up @@ -189,14 +176,14 @@ std::string exportSkill(const Skill &skill)
json += std::string() + "\"name\":\"" + skill.name.c_str() + "\",\n";
json += std::string() + "\"icon\":\"" + skill.icon.c_str() + "\",\n";
json += std::string() + "\"target\":\"" + skillTargetName(skill.target) + "\",\n";
json += std::string() + "\"cost\":" + skillCostJson(skill.cost) + ",\n";
json += std::string() + "\"cost\":" + attributesValueMappingJson(skill.cost) + ",\n";
json += std::string() + "\"range\":" + attributesValueMappingJson(skill.range) + ",\n";
json += std::string() + "\"radius\":" + attributesValueMappingJson(skill.radius) + ",\n";
json += std::string() + "\"duration\":" + attributesValueMappingJson(skill.duration) + ",\n";
json += std::string() + "\"damageAmount\":" + attributesValueMappingJson(skill.damageAmount) + ",\n";
json += std::string() + "\"damageType\":\"" + damageTypeName(skill.damageType) + "\",\n";
json += std::string() + "\"casterAttributes\":" + skillAttributesEffectsJson(skill.casterAttributes) + ",\n";
json += std::string() + "\"targetAttributes\":" + skillAttributesEffectsJson(skill.targetAttributes) + ",\n";
json += std::string() + "\"casterAttributes\":" + skillAttributesJson(skill.casterAttributes) + ",\n";
json += std::string() + "\"targetAttributes\":" + skillAttributesJson(skill.targetAttributes) + ",\n";

json += "\"casterFlags\":[\n";
for (const std::string &flag : skill.casterFlags)
Expand Down
4 changes: 2 additions & 2 deletions sources/generateFloor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,11 +276,11 @@ namespace
switch (randomRange(0u, 4u))
{
case 0:
gen = Generate(randomRange(1u, maxLevel)); // default
gen = Generate(randomRange(1u, maxLevel), 0); // default
break;
case 1:
case 2:
gen = Generate(randomRange(max(maxLevel * 3 / 4, 1u), maxLevel)); // stronger than default
gen = Generate(randomRange(max(maxLevel * 3 / 4, 1u), maxLevel), 0); // stronger than default
break;
case 3:
gen = Generate(maxLevel, -randomRange(0u, maxLevel)); // any features, but possibly weak
Expand Down
10 changes: 5 additions & 5 deletions sources/generateItems.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace
{
Skill sk;
sk.goldCost = randomRange(3, 5);
sk.cost.stamina = randomRange(5, 10);
sk.cost[AttributeEnum::Stamina] = randomRange(5, 10);
sk.damageAmount[AttributeEnum::Strength] = sk.addPower(2, AffixEnum::Prefix, "Strong") + 0.5;
sk.damageAmount[AttributeEnum::Scalar] = interpolate(1u, generate.power, sk.addPower(1, AffixEnum::Prefix, "Powerful"));
sk.damageType = DamageTypeEnum::Slash;
Expand Down Expand Up @@ -43,7 +43,7 @@ namespace
{
Skill sk;
sk.goldCost = randomRange(3, 5);
sk.cost.stamina = randomRange(8, 13);
sk.cost[AttributeEnum::Stamina] = randomRange(8, 13);
sk.damageAmount[AttributeEnum::Dexterity] = sk.addPower(2, AffixEnum::Prefix, "Swift") + 0.5;
sk.damageAmount[AttributeEnum::Scalar] = interpolate(1u, generate.power, sk.addPower(1, AffixEnum::Prefix, "Powerful"));
sk.damageType = DamageTypeEnum::Piercing;
Expand Down Expand Up @@ -78,7 +78,7 @@ namespace
{
Skill sk;
sk.goldCost = randomRange(3, 5);
sk.cost.stamina = randomRange(1, 6);
sk.cost[AttributeEnum::Stamina] = randomRange(1, 6);
sk.range[AttributeEnum::Scalar] = 1;
sk.target = SkillTargetEnum::Character;
sk.casterFlags.push_back(LineOfSight);
Expand Down Expand Up @@ -224,7 +224,7 @@ namespace
{
Skill sk;
sk.goldCost = randomRange(3, 5);
sk.cost.stamina = randomRange(2, 4);
sk.cost[AttributeEnum::Stamina] = randomRange(2, 4);
sk.range[AttributeEnum::Strength] = sk.addPower(0.5) * 0.1;
sk.range[AttributeEnum::Scalar] = 2;
sk.target = SkillTargetEnum::Position;
Expand All @@ -238,7 +238,7 @@ namespace
{
Skill sk;
sk.goldCost = randomRange(3, 5);
sk.cost.stamina = randomRange(3, 6);
sk.cost[AttributeEnum::Stamina] = randomRange(3, 6);
sk.range[AttributeEnum::Constitution] = sk.addPower(0.5) * 0.1;
sk.range[AttributeEnum::Scalar] = 3;
sk.target = SkillTargetEnum::Position;
Expand Down
12 changes: 6 additions & 6 deletions sources/generateSkills.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Skill generateSkill(const Generate &generate)
{
CAGE_ASSERT(valid(generate.magic) && valid(generate.ranged) && valid(generate.support));
generate.valid();

Skill sk;

Expand All @@ -12,9 +12,9 @@ Skill generateSkill(const Generate &generate)
sk.target = SkillTargetEnum::Position;

if (randomChance() < 0.6)
sk.cost.stamina = randomRange(2, 5);
sk.cost[AttributeEnum::Stamina] = randomRange(2, 5);
if (randomChance() < 0.4)
sk.cost.mana = randomRange(2, 5);
sk.cost[AttributeEnum::Mana] = randomRange(2, 5);

if (randomChance() < 0.8)
sk.range[AttributeEnum::Scalar] = randomRange(20, 100);
Expand All @@ -41,9 +41,9 @@ Skill generateSkill(const Generate &generate)
else if (randomChance() < 0.5)
sk.damageType = DamageTypeEnum::Fire;

const auto &sae = []() -> SkillAttributesEffects
const auto &sae = []() -> SkillAttributes
{
SkillAttributesEffects r;
SkillAttributes r;
auto &k = r[AttributeEnum(randomRange(0u, (uint32)AttributeEnum::Scalar))];
if (randomChance() < 0.4)
k[AttributeEnum(randomRange(0, 5))] = randomRange(20, 50);
Expand Down Expand Up @@ -76,7 +76,7 @@ Skill generateSkill(const Generate &generate)
std::string json;
json += "{\n";
json += "\"class\":\"summon\",\n";
json += "\"data\":" + exportMonster(generateMonster(Generate(generate.level))) + "\n";
json += "\"data\":" + exportMonster(generateMonster(Generate(generate.level, generate.powerOffset()))) + "\n";
json += "}";
sk.targetFlags.push_back(std::move(json));
}
Expand Down
2 changes: 1 addition & 1 deletion sources/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace

void generateAll()
{
constexpr uint32 maxLevel = 30;
constexpr uint32 maxLevel = 20;
std::vector<Floor> floors;
floors.reserve(maxLevel);
for (uint32 l = 0; l <= maxLevel; l++)
Expand Down

0 comments on commit 16a7cb9

Please sign in to comment.