[Scummvm-git-logs] scummvm master -> 0bf5460ab3e96201a6ad059cbc3d4fc542f9b8b7
dreammaster
noreply at scummvm.org
Tue May 23 04:34:35 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5f5874ff84 MM: XEEN: Annotate item generation code
0bf5460ab3 MM: XEEN: Fix item enchantments random distribution
Commit: 5f5874ff84fb5a5954830edaa05cb07e5951080a
https://github.com/scummvm/scummvm/commit/5f5874ff84fb5a5954830edaa05cb07e5951080a
Author: Alexander Izmailov (yarolig at gmail.com)
Date: 2023-05-22T21:30:00-07:00
Commit Message:
MM: XEEN: Annotate item generation code
Changed paths:
devtools/create_mm/create_xeen/constants.cpp
engines/mm/xeen/character.cpp
engines/mm/xeen/item.cpp
engines/mm/xeen/item.h
engines/mm/xeen/party.cpp
diff --git a/devtools/create_mm/create_xeen/constants.cpp b/devtools/create_mm/create_xeen/constants.cpp
index 0fb843f5d7f..eae2cd2dc55 100644
--- a/devtools/create_mm/create_xeen/constants.cpp
+++ b/devtools/create_mm/create_xeen/constants.cpp
@@ -514,6 +514,7 @@ const int LangConstants::STAT_BONUSES[24] = {
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20
};
+// fire elec ice acid energy magic
const int LangConstants::ELEMENTAL_CATEGORIES[6] = { 8, 15, 20, 25, 33, 36 };
const int LangConstants::ATTRIBUTE_CATEGORIES[10] = {
@@ -576,34 +577,39 @@ const int LangConstants::ARMOR_STRENGTHS[14] = { 0, 2, 4, 5, 6, 7, 8, 10, 4, 2,
const int LangConstants::MAKE_ITEM_ARR1[6] = { 0, 8, 15, 20, 25, 33 };
const int LangConstants::MAKE_ITEM_ARR2[6][7][2] = {
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 7 }, { 7, 7 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 1, 2 }, { 2, 2 }, { 2, 3 }, { 3, 3 } }
+ // L1 L2 L3 L4 L5 L6 L7
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } }, // fire
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 7 }, { 7, 7 } }, // electricity
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 5 }, { 5, 5 } }, // frost
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } }, // acid
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } }, // energy
+ { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 1, 2 }, { 2, 2 }, { 2, 3 }, { 3, 3 } } // magic
};
const int LangConstants::MAKE_ITEM_ARR3[10][7][2] = {
- { { 0, 0 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 10 }, { 10, 10 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } },
- { { 0, 0 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, { 5, 6 }, { 6, 6 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } },
- { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } },
- { { 0, 0 }, { 1, 2 }, { 1, 4 }, { 3, 6 }, { 5, 8 }, { 7, 10 }, { 10, 10 } }
+ // L1 L2 L3 L4 L5 L6 L7
+ { { 0, 0 }, { 1, 4 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 6, 10 }, { 10, 10 } }, // str
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } }, // int
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } }, // per
+ { { 0, 0 }, { 1, 3 }, { 2, 5 }, { 3, 6 }, { 4, 7 }, { 5, 8 }, { 8, 8 } }, // spd
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } }, // acc
+ { { 0, 0 }, { 1, 2 }, { 2, 3 }, { 3, 4 }, { 4, 5 }, { 5, 6 }, { 6, 6 } }, // luc
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } }, // hp
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 5 }, { 4, 6 }, { 6, 6 } }, // sp
+ { { 0, 0 }, { 1, 2 }, { 1, 3 }, { 2, 4 }, { 3, 4 }, { 4, 5 }, { 5, 5 } }, // ac
+ { { 0, 0 }, { 1, 2 }, { 1, 4 }, { 3, 6 }, { 5, 8 }, { 7, 10 }, { 10, 10 } } // thievery
};
const int LangConstants::MAKE_ITEM_ARR4[2][7][2] = {
- { { 0, 0 }, { 1, 4 }, { 3, 7 }, { 4, 8 }, { 5, 9 }, { 8, 9 }, { 9, 9 } },
- { { 0, 0 }, { 1, 4 }, { 2, 6 }, { 4, 7 }, { 6, 10 }, { 9, 13 }, { 13, 13 } }
+ // L1 L2 L3 L4 L5 L6 L7
+ { { 0, 0 }, { 1, 4 }, { 3, 7 }, { 4, 8 }, { 5, 9 }, { 8, 9 }, { 9, 9 } }, // common
+ { { 0, 0 }, { 1, 4 }, { 2, 6 }, { 4, 7 }, { 6, 10 }, { 9, 13 }, { 13, 13 } } // rare and precious
};
const int LangConstants::MAKE_ITEM_ARR5[8][2] = {
+ // L1 L2 L3 L4
{ 0, 0 }, { 1, 15 }, { 16, 30 }, { 31, 40 }, { 41, 50 },
+ // L5 L6 L7
{ 51, 60 }, { 61, 73 }, { 61, 73 }
};
diff --git a/engines/mm/xeen/character.cpp b/engines/mm/xeen/character.cpp
index 0b0476b3fb2..7549c2c18c2 100644
--- a/engines/mm/xeen/character.cpp
+++ b/engines/mm/xeen/character.cpp
@@ -561,8 +561,9 @@ int Character::itemScan(int itemId) const {
const XeenItem &item = _weapons[idx];
if (item._frame && !item.isBad() && itemId < 11
- && itemId != 3 && item._material >= 59 && item._material <= 130) {
+ && itemId != ENDURANCE && item._material >= 59 && item._material <= 130) {
int mIndex = (int)item.getAttributeCategory();
+ // There is no Endurance bonus. This enchantment category skipped.
if (mIndex > PERSONALITY)
++mIndex;
@@ -971,21 +972,21 @@ int Character::getNumAwards() const {
return total;
}
-ItemCategory Character::makeItem(int p1, int itemIndex, int p3) {
+ItemCategory Character::makeItem(int itemLevel, int itemIndex, int reason) {
XeenEngine *vm = Party::_vm;
int itemOffset = vm->getGameID() == GType_Swords ? 6 : 0;
- if (!p1)
+ if (!itemLevel)
return CATEGORY_WEAPON;
int itemId = 0;
- int v4 = vm->getRandomNumber(100);
- int v6 = vm->getRandomNumber(p1 < 6 ? 100 : 80);
+ int categoryRN = vm->getRandomNumber(100);
+ int subcategoryRN = vm->getRandomNumber(itemLevel < 6 ? 100 : 80);
ItemCategory category;
- int v16 = 0, v14 = 0, miscCharges = 0, miscId = 0, v8 = 0, v12 = 0;
+ int material = 0, attrBonus = 0, miscCharges = 0, miscId = 0, enchantmentType = 0, element = 0;
// Randomly pick a category and item Id
- if (p3 == 12) {
+ if (reason == MAKE_ITEM_SPECIAL_EVENT) {
if (_itemType < (35 + itemOffset)) {
category = CATEGORY_WEAPON;
itemId = _itemType;
@@ -1000,80 +1001,81 @@ ItemCategory Character::makeItem(int p1, int itemIndex, int p3) {
itemId = _itemType - (60 + itemOffset);
}
} else {
- switch (p3) {
- case 1:
- v4 = 35;
+ switch (reason) {
+ case MAKE_ITEM_ENCHANT_WEAPON:
+ categoryRN = 35;
break;
- case 2:
- v4 = 60;
+ case MAKE_ITEM_ENCHANT_ARMOR:
+ categoryRN = 60;
break;
- case 3:
- v4 = 100;
+ case MAKE_ITEM_ENCHANT_ACCESSORY: // never used
+ categoryRN = 100;
break;
default:
break;
}
- if (p1 == 1) {
- if (v4 <= 40) {
+ if (itemLevel == 1) {
+ if (categoryRN <= 40) {
category = CATEGORY_WEAPON;
- if (v6 <= 30) {
- itemId = vm->getRandomNumber(1, 6);
- } else if (v6 <= 60) {
- itemId = vm->getRandomNumber(7, 17);
- } else if (v6 <= 85) {
- itemId = vm->getRandomNumber(18, 29);
+ if (subcategoryRN <= 30) {
+ itemId = vm->getRandomNumber(1, 6); // swords
+ } else if (subcategoryRN <= 60) {
+ itemId = vm->getRandomNumber(7, 17); // one-handed
+ } else if (subcategoryRN <= 85) {
+ itemId = vm->getRandomNumber(18, 29); // two-handed
} else {
- itemId = vm->getRandomNumber(30, 33);
+ itemId = vm->getRandomNumber(30, 33); // ranged
}
- } else if (v4 <= 85) {
+ } else if (categoryRN <= 85) {
category = CATEGORY_ARMOR;
- itemId = vm->getRandomNumber(1, 7);
+ itemId = vm->getRandomNumber(1, 7); // armor
} else {
category = CATEGORY_MISC;
- itemId = vm->getRandomNumber(1, 9);
+ itemId = vm->getRandomNumber(1, 9); // wand
}
- } else if (v4 <= 35) {
+ } else if (categoryRN <= 35) {
category = CATEGORY_WEAPON;
- if (v6 <= 30) {
- itemId = vm->getRandomNumber(1, 6);
- } else if (v6 <= 60) {
- itemId = vm->getRandomNumber(7, 17);
- } else if (v6 <= 85) {
- itemId = vm->getRandomNumber(18, 29);
+ if (subcategoryRN <= 30) {
+ itemId = vm->getRandomNumber(1, 6); // swords
+ } else if (subcategoryRN <= 60) {
+ itemId = vm->getRandomNumber(7, 17); // one-handed
+ } else if (subcategoryRN <= 85) {
+ itemId = vm->getRandomNumber(18, 29); // two-handed
} else {
- itemId = vm->getRandomNumber(30, 33);
+ itemId = vm->getRandomNumber(30, 33); // ranged
}
- } else if (v4 <= 60) {
+ } else if (categoryRN <= 60) {
category = CATEGORY_ARMOR;
- itemId = (v6 > 70) ? 8 : vm->getRandomNumber(1, 7);
- } else if (v6 <= 10) {
+ itemId = (subcategoryRN > 70) ? 8 : vm->getRandomNumber(1, 7); // shield or armor
+
+ } else if (subcategoryRN <= 10) {
category = CATEGORY_ARMOR;
- itemId = 9;
- } else if (v6 <= 20) {
+ itemId = 9; // helm
+ } else if (subcategoryRN <= 20) {
category = CATEGORY_ARMOR;
- itemId = 13;
- } else if (v6 <= 35) {
+ itemId = 13; // gauntlets
+ } else if (subcategoryRN <= 35) {
category = CATEGORY_ACCESSORY;
- itemId = 1;
- } else if (v6 <= 45) {
+ itemId = 1; // ring
+ } else if (subcategoryRN <= 45) {
category = CATEGORY_ARMOR;
- itemId = 10;
- } else if (v6 <= 55) {
+ itemId = 10; // boots
+ } else if (subcategoryRN <= 55) {
category = CATEGORY_ARMOR;
- itemId = vm->getRandomNumber(11, 12);
- } else if (v6 <= 65) {
+ itemId = vm->getRandomNumber(11, 12); // cloak, cape
+ } else if (subcategoryRN <= 65) {
category = CATEGORY_ACCESSORY;
- itemId = 2;
- } else if (v6 <= 75) {
+ itemId = 2; // belt
+ } else if (subcategoryRN <= 75) {
category = CATEGORY_ACCESSORY;
- itemId = vm->getRandomNumber(3, 7);
- } else if (v6 <= 80) {
+ itemId = vm->getRandomNumber(3, 7); // medal-like
+ } else if (subcategoryRN <= 80) {
category = CATEGORY_ACCESSORY;
- itemId = vm->getRandomNumber(8, 10);
+ itemId = vm->getRandomNumber(8, 10); // amulet-like
} else {
category = CATEGORY_MISC;
- itemId = vm->getRandomNumber(1, 9);
+ itemId = vm->getRandomNumber(1, 9); // wand-like
}
}
@@ -1081,101 +1083,111 @@ ItemCategory Character::makeItem(int p1, int itemIndex, int p3) {
newItem.clear();
newItem._id = itemId;
- v4 = vm->getRandomNumber(1, 100);
+ int enchanntmentRN = vm->getRandomNumber(1, 100);
switch (category) {
case CATEGORY_WEAPON:
case CATEGORY_ARMOR:
- if (p1 != 1) {
- if (v4 <= 70) {
- v8 = 3;
- } else if (v4 <= 98) {
- v8 = 1;
+ if (itemLevel != 1) {
+ if (enchanntmentRN <= 70) {
+ enchantmentType = ENCHANTMENT_TYPE_MATERIAL;
+ } else if (enchanntmentRN <= 98) {
+ enchantmentType = ENCHANTMENT_TYPE_ELEMENT;
} else {
- v8 = 2;
+ enchantmentType = ENCHANTMENT_TYPE_ATTR_BONUS;
}
}
break;
case CATEGORY_ACCESSORY:
- if (v4 <= 20) {
- v8 = 3;
- } else if (v4 <= 60) {
- v8 = 1;
+ if (enchanntmentRN <= 20) {
+ enchantmentType = ENCHANTMENT_TYPE_MATERIAL;
+ } else if (enchanntmentRN <= 60) {
+ enchantmentType = ENCHANTMENT_TYPE_ELEMENT;
} else {
- v8 = 2;
+ enchantmentType = ENCHANTMENT_TYPE_ATTR_BONUS;
}
break;
case CATEGORY_MISC:
newItem._material = itemId;
- v8 = 4;
+ enchantmentType = ENCHANTMENT_TYPE_USABLE;
break;
default:
break;
}
- if (p1 != 1 || category == CATEGORY_MISC) {
- int rval, mult;
- switch (v8) {
- case 1:
- rval = vm->getRandomNumber(1, 100);
- if (rval <= 25) {
- mult = 0;
- } else if (rval <= 45) {
- mult = 1;
- } else if (rval <= 60) {
- mult = 2;
- } else if (rval <= 75) {
- mult = 3;
- } else if (rval <= 95) {
- mult = 4;
+ if (itemLevel != 1 || category == CATEGORY_MISC) {
+ int rn, enchantmentSubtype, r1, r2;
+ switch (enchantmentType) {
+ case ENCHANTMENT_TYPE_ELEMENT:
+ rn = vm->getRandomNumber(1, 100);
+ if (rn <= 25) {
+ enchantmentSubtype = ELEM_FIRE;
+ } else if (rn <= 45) {
+ enchantmentSubtype = ELEM_ELECTRICITY;
+ } else if (rn <= 60) {
+ enchantmentSubtype = ELEM_COLD;
+ } else if (rn <= 75) {
+ enchantmentSubtype = ELEM_ACID_POISON;
+ } else if (rn <= 95) {
+ enchantmentSubtype = ELEM_ENERGY;
} else {
- mult = 5;
+ enchantmentSubtype = ELEM_MAGIC;
}
- v12 = Res.MAKE_ITEM_ARR1[vm->getRandomNumber(Res.MAKE_ITEM_ARR2[mult][p1][0],
- Res.MAKE_ITEM_ARR2[mult][p1][1])];
+ r1 = Res.MAKE_ITEM_ARR2[enchantmentSubtype][itemLevel][0];
+ r2 = Res.MAKE_ITEM_ARR2[enchantmentSubtype][itemLevel][1];
+ element = Res.MAKE_ITEM_ARR1[vm->getRandomNumber(r1, r2)];
break;
-
- case 2:
- rval = vm->getRandomNumber(1, 100);
- if (rval <= 15) {
- mult = 0;
- } else if (rval <= 25) {
- mult = 1;
- } else if (rval <= 35) {
- mult = 2;
- } else if (rval <= 50) {
- mult = 3;
- } else if (rval <= 65) {
- mult = 4;
- } else if (rval <= 80) {
- mult = 5;
- } else if (rval <= 85) {
- mult = 6;
- } else if (rval <= 90) {
- mult = 7;
- } else if (rval <= 95) {
- mult = 8;
+ case ENCHANTMENT_TYPE_ATTR_BONUS:
+ rn = vm->getRandomNumber(1, 100);
+ if (rn <= 15) {
+ enchantmentSubtype = ATTR_MIGHT;
+ } else if (rn <= 25) {
+ enchantmentSubtype = ATTR_INTELLECT;
+ } else if (rn <= 35) {
+ enchantmentSubtype = ATTR_PERSONALITY;
+ } else if (rn <= 50) {
+ enchantmentSubtype = ATTR_SPEED;
+ } else if (rn <= 65) {
+ enchantmentSubtype = ATTR_ACCURACY;
+ } else if (rn <= 80) {
+ enchantmentSubtype = ATTR_LUCK;
+ } else if (rn <= 85) {
+ enchantmentSubtype = ATTR_HIT_POINTS;
+ } else if (rn <= 90) {
+ enchantmentSubtype = ATTR_SPELL_POINTS;
+ } else if (rn <= 95) {
+ enchantmentSubtype = ATTR_ARMOR_CLASS;
} else {
- mult = 9;
+ enchantmentSubtype = ATTR_THIEVERY;
}
- v14 = Res.MAKE_ITEM_ARR1[vm->getRandomNumber(Res.MAKE_ITEM_ARR3[mult][p1][0],
- Res.MAKE_ITEM_ARR3[mult][p1][1])];
+ r1 = Res.MAKE_ITEM_ARR3[enchantmentSubtype][itemLevel][0];
+ r2 = Res.MAKE_ITEM_ARR3[enchantmentSubtype][itemLevel][1];
+ // wrong formula here:
+ attrBonus = Res.MAKE_ITEM_ARR1[vm->getRandomNumber(r1, r2)];
break;
- case 3:
- mult = p1 == 7 || vm->getRandomNumber(1, 100) > 70 ? 1 : 0;
- v16 = vm->getRandomNumber(Res.MAKE_ITEM_ARR4[mult][p1 - 1][0],
- Res.MAKE_ITEM_ARR4[mult][p1 - 1][1]);
- if (mult)
- v16 += 9;
+ case ENCHANTMENT_TYPE_MATERIAL:
+ enchantmentSubtype = itemLevel == 7 || vm->getRandomNumber(1, 100) > 70 ? 1 : 0;
+
+ // It is unclear why itemLevel - 1 is here.
+ r1 = Res.MAKE_ITEM_ARR4[enchantmentSubtype][itemLevel - 1][0];
+ r2 = Res.MAKE_ITEM_ARR4[enchantmentSubtype][itemLevel - 1][1];
+ material = vm->getRandomNumber(r1, r2);
+
+ // Change from common/rare to rare/precious
+ if (enchantmentSubtype)
+ material += 9;
break;
- case 4:
- miscId = vm->getRandomNumber(Res.MAKE_ITEM_ARR5[p1][0], Res.MAKE_ITEM_ARR5[p1][1]);
+ case ENCHANTMENT_TYPE_USABLE:
+ r1 = Res.MAKE_ITEM_ARR5[itemLevel][0];
+ r2 = Res.MAKE_ITEM_ARR5[itemLevel][1];
+
+ miscId = vm->getRandomNumber(r1, r2);
miscCharges = vm->getRandomNumber(1, 8);
break;
@@ -1186,17 +1198,25 @@ ItemCategory Character::makeItem(int p1, int itemIndex, int p3) {
switch (category) {
case CATEGORY_WEAPON:
- if (p1 != 1) {
- newItem._material = (v14 ? v14 + 58 : 0) + (v16 ? v16 + 36 : 0) + v12;
- if (vm->getRandomNumber(20) == 10)
- newItem._state._counter = vm->getRandomNumber(1, 6);
+ if (itemLevel != 1) {
+ newItem._material = (attrBonus ? attrBonus + 58 : 0) +
+ (material ? material + 36 : 0) +
+ element;
+
+
+ if (vm->getRandomNumber(20) == 10) {
+ // of undead/golem/dragon/etc-slaying
+ newItem._state._counter = vm->getRandomNumber(EFFECTIVE_DRAGON, EFFECTIVE_ANIMAL);
+ }
}
break;
case CATEGORY_ARMOR:
case CATEGORY_ACCESSORY:
- if (p1 != 1) {
- newItem._material = (v14 ? v14 + 58 : 0) + (v16 ? v16 + 36 : 0) + v12;
+ if (itemLevel != 1) {
+ newItem._material = (attrBonus ? attrBonus + 58 : 0) +
+ (material ? material + 36 : 0) +
+ element;
}
break;
diff --git a/engines/mm/xeen/item.cpp b/engines/mm/xeen/item.cpp
index 763128efa4c..aa7c92eb47a 100644
--- a/engines/mm/xeen/item.cpp
+++ b/engines/mm/xeen/item.cpp
@@ -383,7 +383,8 @@ void WeaponItems::enchantItem(int itemIndex, int amount) {
Character tempCharacter;
if (item._material == 0 && item._state.empty() && item._id < XEEN_SLAYER_SWORD) {
- tempCharacter.makeItem(amount, 0, 1);
+ // make a random enchanted weapon and then copy its enchantments
+ tempCharacter.makeItem(amount, 0, MAKE_ITEM_ENCHANT_WEAPON);
XeenItem &tempItem = tempCharacter._weapons[0];
if (tempItem._material != 0 || !tempItem._state.empty()) {
@@ -565,7 +566,8 @@ void ArmorItems::enchantItem(int itemIndex, int amount) {
Character tempCharacter;
if (item._material == 0 && item._state.empty()) {
- tempCharacter.makeItem(amount, 0, 2);
+ // make a random enchanted armor and then copy its enchantments
+ tempCharacter.makeItem(amount, 0, MAKE_ITEM_ENCHANT_ARMOR);
XeenItem &tempItem = tempCharacter._armor[0];
if (tempItem._material != 0 || !tempItem._state.empty()) {
diff --git a/engines/mm/xeen/item.h b/engines/mm/xeen/item.h
index 125128216e1..257ee6306e8 100644
--- a/engines/mm/xeen/item.h
+++ b/engines/mm/xeen/item.h
@@ -52,6 +52,11 @@ enum ElementalCategory {
ELEM_ENERGY = 4, ELEM_MAGIC = 5
};
+enum EnchantmentType {
+ ENCHANTMENT_TYPE_ELEMENT = 1, ENCHANTMENT_TYPE_ATTR_BONUS = 2,
+ ENCHANTMENT_TYPE_MATERIAL = 3, ENCHANTMENT_TYPE_USABLE = 4
+};
+
enum WeaponId {
XEEN_SLAYER_SWORD = 34
};
@@ -61,6 +66,11 @@ enum Effectiveness {
EFFECTIVE_INSECT = 4, EFFEctIVE_MONSTERS = 5, EFFECTIVE_ANIMAL = 6
};
+enum MakeItemReason {
+ MAKE_ITEM_ENCHANT_WEAPON = 1, MAKE_ITEM_ENCHANT_ARMOR = 2,
+ MAKE_ITEM_ENCHANT_ACCESSORY = 3, MAKE_ITEM_SPECIAL_EVENT = 12
+};
+
struct ItemState {
byte _counter : 6; // Stores charges for Misc items, and the effective against for weapons
bool _cursed : 1;
diff --git a/engines/mm/xeen/party.cpp b/engines/mm/xeen/party.cpp
index 2a25234c320..f9f2aac9a7c 100644
--- a/engines/mm/xeen/party.cpp
+++ b/engines/mm/xeen/party.cpp
@@ -1385,7 +1385,7 @@ bool Party::giveTake(int takeMode, uint takeVal, int giveMode, uint giveVal, int
}
// Create the item and it's category
- ItemCategory itemCat = tempChar.makeItem(giveVal, 0, (idx == -1) ? 0 : 12);
+ ItemCategory itemCat = tempChar.makeItem(giveVal, 0, (idx == -1) ? 0 : MAKE_ITEM_SPECIAL_EVENT);
XeenItem &srcItem = tempChar._items[itemCat][0];
XeenItem *trItems = _treasure[itemCat];
Commit: 0bf5460ab3e96201a6ad059cbc3d4fc542f9b8b7
https://github.com/scummvm/scummvm/commit/0bf5460ab3e96201a6ad059cbc3d4fc542f9b8b7
Author: Alexander Izmailov (yarolig at gmail.com)
Date: 2023-05-22T21:30:05-07:00
Commit Message:
MM: XEEN: Fix item enchantments random distribution
Changed paths:
engines/mm/xeen/character.cpp
engines/mm/xeen/item.cpp
diff --git a/engines/mm/xeen/character.cpp b/engines/mm/xeen/character.cpp
index 7549c2c18c2..66d8688b25d 100644
--- a/engines/mm/xeen/character.cpp
+++ b/engines/mm/xeen/character.cpp
@@ -973,6 +973,9 @@ int Character::getNumAwards() const {
}
ItemCategory Character::makeItem(int itemLevel, int itemIndex, int reason) {
+ assert(1 <= itemLevel && itemLevel <= 7);
+ assert(0 <= itemIndex && itemIndex < INV_ITEMS_TOTAL);
+
XeenEngine *vm = Party::_vm;
int itemOffset = vm->getGameID() == GType_Swords ? 6 : 0;
@@ -981,6 +984,7 @@ ItemCategory Character::makeItem(int itemLevel, int itemIndex, int reason) {
int itemId = 0;
int categoryRN = vm->getRandomNumber(100);
+ // generate no wands, no bows and less two-handed weapons on levels 6 and 7
int subcategoryRN = vm->getRandomNumber(itemLevel < 6 ? 100 : 80);
ItemCategory category;
int material = 0, attrBonus = 0, miscCharges = 0, miscId = 0, enchantmentType = 0, element = 0;
@@ -1084,6 +1088,7 @@ ItemCategory Character::makeItem(int itemLevel, int itemIndex, int reason) {
newItem._id = itemId;
int enchanntmentRN = vm->getRandomNumber(1, 100);
+
switch (category) {
case CATEGORY_WEAPON:
case CATEGORY_ARMOR:
@@ -1136,9 +1141,9 @@ ItemCategory Character::makeItem(int itemLevel, int itemIndex, int reason) {
enchantmentSubtype = ELEM_MAGIC;
}
- r1 = Res.MAKE_ITEM_ARR2[enchantmentSubtype][itemLevel][0];
- r2 = Res.MAKE_ITEM_ARR2[enchantmentSubtype][itemLevel][1];
- element = Res.MAKE_ITEM_ARR1[vm->getRandomNumber(r1, r2)];
+ r1 = Res.MAKE_ITEM_ARR2[enchantmentSubtype][itemLevel - 1][0];
+ r2 = Res.MAKE_ITEM_ARR2[enchantmentSubtype][itemLevel - 1][1];
+ element = Res.MAKE_ITEM_ARR1[enchantmentSubtype] + vm->getRandomNumber(r1, r2);
break;
case ENCHANTMENT_TYPE_ATTR_BONUS:
rn = vm->getRandomNumber(1, 100);
@@ -1164,16 +1169,19 @@ ItemCategory Character::makeItem(int itemLevel, int itemIndex, int reason) {
enchantmentSubtype = ATTR_THIEVERY;
}
- r1 = Res.MAKE_ITEM_ARR3[enchantmentSubtype][itemLevel][0];
- r2 = Res.MAKE_ITEM_ARR3[enchantmentSubtype][itemLevel][1];
- // wrong formula here:
- attrBonus = Res.MAKE_ITEM_ARR1[vm->getRandomNumber(r1, r2)];
+ {
+ // similar to Res.ATTRIBUTE_CATEGORIES
+ const int SUBTYPE_OFFSETS[] = {0, 10, 18, 26, 34, 40, 46, 51, 57, 62, 72};
+
+ r1 = Res.MAKE_ITEM_ARR3[enchantmentSubtype][itemLevel - 1][0];
+ r2 = Res.MAKE_ITEM_ARR3[enchantmentSubtype][itemLevel - 1][1];
+ attrBonus = SUBTYPE_OFFSETS[enchantmentSubtype] + vm->getRandomNumber(r1, r2);
+ }
break;
case ENCHANTMENT_TYPE_MATERIAL:
- enchantmentSubtype = itemLevel == 7 || vm->getRandomNumber(1, 100) > 70 ? 1 : 0;
- // It is unclear why itemLevel - 1 is here.
+ enchantmentSubtype = itemLevel == 7 || vm->getRandomNumber(1, 100) > 70 ? 1 : 0;
r1 = Res.MAKE_ITEM_ARR4[enchantmentSubtype][itemLevel - 1][0];
r2 = Res.MAKE_ITEM_ARR4[enchantmentSubtype][itemLevel - 1][1];
material = vm->getRandomNumber(r1, r2);
diff --git a/engines/mm/xeen/item.cpp b/engines/mm/xeen/item.cpp
index aa7c92eb47a..09a88fec9dd 100644
--- a/engines/mm/xeen/item.cpp
+++ b/engines/mm/xeen/item.cpp
@@ -64,11 +64,12 @@ void XeenItem::synchronize(Common::Serializer &s) {
}
ElementalCategory XeenItem::getElementalCategory() const {
- assert(_material < 36);
+ assert(_material <= 36);
return getElementalCategory(_material);
}
ElementalCategory XeenItem::getElementalCategory(int material) {
+ assert(material <= 36);
int idx;
for (idx = 0; Res.ELEMENTAL_CATEGORIES[idx] < material; ++idx)
;
@@ -77,6 +78,7 @@ ElementalCategory XeenItem::getElementalCategory(int material) {
}
AttributeCategory XeenItem::getAttributeCategory() const {
+ assert(59 <= _material && _material <= 130);
int m = _material - 59;
int idx;
for (idx = 0; Res.ATTRIBUTE_CATEGORIES[idx] < m; ++idx)
More information about the Scummvm-git-logs
mailing list