Want more features on Pastebin? Sign Up, it's FREE!
Guest

updated script

By: a guest on Mar 18th, 2015  |  syntax: None  |  size: 47.79 KB  |  views: 124  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print  |  QR code  |  clone
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include "gs_inc_common"
  2. #include "mi_log"
  3.  
  4. // The PropertyStruct is used to pass information about properties between functions.
  5. struct PropertyStruct
  6. {
  7.     // The id corresponds to one of the constants below, depending on gear type.
  8.     int id;
  9.  
  10.     // The modifiers are used to store each property value.
  11.     // The first modifier is usually the type of property, e.g. cold resistance.
  12.     int mod1;
  13.  
  14.     // The second modifier is usually the amount of the property, e.g. +3.
  15.     int mod2;
  16. };
  17.  
  18. // The ProperyVarNameStruct is used to pass the string names for each index so that
  19. // they can be accesses in a consistent way using Get/SetLocalVariable.
  20. struct PropertyVarNameStruct
  21. {
  22.     string id;
  23.     string mod1;
  24.     string mod2;
  25. };
  26.  
  27. // The max number of properties that can be spawned on an artifact.
  28. const int MAX_PROPERTY_COUNT = 4;
  29.  
  30. const int WEAPON_PROPERTY_COUNT     = 10;
  31.  
  32. const int WEAPON_ENH_BONUS          = 0;
  33. const int WEAPON_AB_BONUS           = 1;
  34. const int WEAPON_ENH_BONUS_VS_RACE  = 2;
  35. const int WEAPON_ELEMENTAL_DAMAGE   = 3;
  36. const int WEAPON_ABILITY_BONUS      = 4;
  37. const int WEAPON_SKILL_BONUS        = 5;
  38. const int WEAPON_MASSIVE_CRITICALS  = 6;
  39. const int WEAPON_MISC_BONUSES       = 7;
  40. const int WEAPON_AMMO_OR_VAMP_REGEN = 8;
  41. const int WEAPON_USAGE_RESTRICTION  = 9;
  42.  
  43. const int ARMOUR_PROPERTY_COUNT      = 8;
  44.  
  45. const int ARMOUR_AC_BONUS            = 0;
  46. const int ARMOUR_AC_BONUS_VS_RACE    = 1;
  47. const int ARMOUR_SAVE_BONUS          = 2;
  48. const int ARMOUR_SPECIFIC_SAVE_BONUS = 3;
  49. const int ARMOUR_ELEMENTAL_DR        = 4;
  50. const int ARMOUR_ABILITY_BONUS       = 5;
  51. const int ARMOUR_SKILL_BONUS         = 6;
  52. const int ARMOUR_USAGE_RESTRICTION   = 7;
  53.  
  54. const int GEAR_PROPERTY_COUNT      = 8;
  55.  
  56. const int GEAR_AC_BONUS            = 0;
  57. const int GEAR_AC_BONUS_VS_RACE    = 1;
  58. const int GEAR_SAVE_BONUS          = 2;
  59. const int GEAR_SPECIFIC_SAVE_BONUS = 3;
  60. const int GEAR_ELEMENTAL_DR        = 4;
  61. const int GEAR_ABILITY_BONUS       = 5;
  62. const int GEAR_SKILL_BONUS         = 6;
  63. const int GEAR_USAGE_RESTRICTION   = 7;
  64.  
  65. const int USAGE_RESTRICTION_CLASS = 0;
  66. const int USAGE_RESTRICTION_RACE  = 1;
  67.  
  68. const int MISC_BONUS_VISUAL  = 1;
  69. const int MISC_BONUS_FREEDOM = 2;
  70. const int MISC_BONUS_FEAR    = 3;
  71. const int MISC_BONUS_LIGHT   = 4;
  72.  
  73. const int ITEM_TYPE_WEAPON = 0;
  74. const int ITEM_TYPE_ARMOUR = 1;
  75. const int ITEM_TYPE_GEAR   = 2;
  76.  
  77. const int INVALID_PROPERTY = -1;
  78.  
  79. // The maximum amount of gold that can spawn in an artifact chest.
  80. const int PICKUP_GOLD_LIMIT = 1000;
  81.  
  82. // The lowest possible value of an artifact.
  83. // This is set to 250 by default to avoid the useless artifacts that are generated with
  84. // only one property, which is a restriction property.
  85. const int GOLD_FLOOR = 250;
  86.  
  87. // Creates a weapon of a random type on OBJECT_SELF and returns it.
  88. object createWeapon();
  89.  
  90. // Creates armour of a random type on OBJECT_SELF and returns it.
  91. object createArmour();
  92.  
  93. // Creates gear of a random type on OBJECT_SELF and returns it.
  94. object createGear();
  95.  
  96. // Applies randomly generated properties suitable for a weapon to an item.
  97. // If ranged is true, can generate unlimited ammo, otherwise, can generate vamp regen.
  98. void applyWeaponStats(object weapon, int ranged);
  99.  
  100. // Applies randomly generated properties suitable for armour to an item.
  101. void applyArmourStats(object armour);
  102.  
  103. // Applies randomly generated properties suitable for gear to an item.
  104. void applyGearStats(object gear);
  105.  
  106. // Applies the generic artifact name and "found at <x>" description to the item.
  107. void applyDescription(object item);
  108.  
  109. // Fetches the property with the given index from the current object's variable list.
  110. struct PropertyStruct getProperty(int index);
  111.  
  112. // Sets the property with the given index from the current object's variable list.
  113. void setProperty(int index, struct PropertyStruct property);
  114.  
  115. // Returns a unique property that is not already present on the item.
  116. struct PropertyStruct getUniqueWeaponProperty(int ranged);
  117.  
  118. // Returns a unique property that is not already present on the item.
  119. struct PropertyStruct getUniqueArmourProperty();
  120.  
  121. // Returns a unique property that is not already present on the item.
  122. struct PropertyStruct getUniqueGearProperty();
  123.  
  124. // Returns true if the provided property is valid and unique, or false otherwise.
  125. int isWeaponPropertyValid(struct PropertyStruct property);
  126.  
  127. // Returns true if the provided property is valid and unique, or false otherwise.
  128. int isArmourPropertyValid(struct PropertyStruct property);
  129.  
  130. // Returns true if the provided property is valid and unique, or false otherwise.
  131. int isGearPropertyValid(struct PropertyStruct property);
  132.  
  133. // Checks if the property with the given index from the current object's variable list is set.
  134. int isPropertyUsed(int property);
  135.  
  136. // Locates and returns the property with the provided id.
  137. // Optionally, provide a second integer to skip n hits.
  138. struct PropertyStruct findProperty(int propertyId, int nth = 0);
  139.  
  140. // Returns a struct of property var names for the given index, to acces with Get/SetLocalVariable.
  141. struct PropertyVarNameStruct getPropertyVarNames(int index);
  142.  
  143. // Unsets the variables 0 -> MAX_PROPERTY_COUNT.
  144. void cleanupPropertyVars();
  145.  
  146. // Outputs the generated properties to a log file.
  147. void writePropertiesToLog(int propertyCount, int itemType);
  148.  
  149. // Utility method to return a basic object resref of the provided type.
  150. string getResRefByItemType(int itemType);
  151.  
  152. void main()
  153. {
  154.     if (GetLocalInt(OBJECT_SELF, "GS_ENABLED") || GetIsObjectValid(GetFirstItemInInventory()))  
  155.     {  
  156.         return;
  157.     }
  158.  
  159.     cleanupPropertyVars();
  160.  
  161.     object item = OBJECT_INVALID;
  162.     string containerTag = GetTag(OBJECT_SELF);
  163.  
  164.     do
  165.     {
  166.         if (containerTag == "GS_WEAPON_UNIQUE")
  167.         {
  168.             item = createWeapon();
  169.  
  170.             if (!GetIsObjectValid(item))
  171.             {
  172.                 return;
  173.             }
  174.  
  175.             int itemType = GetBaseItemType(item);
  176.  
  177.             // Only count ranged weapons that consume separate ammunition as ranged.
  178.             int ranged = itemType == BASE_ITEM_HEAVYCROSSBOW ||
  179.                          itemType == BASE_ITEM_LIGHTCROSSBOW ||
  180.                          itemType == BASE_ITEM_LONGBOW ||
  181.                          itemType == BASE_ITEM_SHORTBOW ||
  182.                          itemType == BASE_ITEM_SLING;
  183.  
  184.             applyWeaponStats(item, ranged);
  185.         }
  186.         else if (containerTag == "GS_ARMOR_UNIQUE")
  187.         {
  188.             item = createArmour();
  189.  
  190.             if (!GetIsObjectValid(item))
  191.             {
  192.                 return;
  193.             }
  194.  
  195.             applyArmourStats(item);
  196.         }
  197.         else if (containerTag == "GS_TREASURE_UNIQUE")
  198.         {
  199.             item = createGear();
  200.  
  201.             if (!GetIsObjectValid(item))
  202.             {
  203.                 return;
  204.             }
  205.  
  206.             applyGearStats(item);
  207.         }
  208.  
  209.         if (GetGoldPieceValue(item) < GOLD_FLOOR)
  210.         {
  211.             DestroyObject(item);
  212.             item = OBJECT_INVALID;
  213.         }
  214.     } while (item == OBJECT_INVALID);
  215.  
  216.     applyDescription(item);
  217.     SetIdentified(item, FALSE);
  218.     gsCMCreateGold(Random(PICKUP_GOLD_LIMIT) + 1);
  219.  
  220.     if (!GetIsObjectValid(GetLastKiller()))
  221.     {
  222.         SetLocalInt(OBJECT_SELF, "GS_ENABLED", TRUE);
  223.     }
  224. }
  225.  
  226. object createWeapon()
  227. {
  228.     int itemType = 0;
  229.  
  230.     switch(Random(36))
  231.     {
  232.         case 0:  itemType = BASE_ITEM_SHORTSWORD; break;
  233.         case 1:  itemType = BASE_ITEM_LONGSWORD; break;
  234.         case 2:  itemType = BASE_ITEM_BATTLEAXE; break;
  235.         case 3:  itemType = BASE_ITEM_BASTARDSWORD; break;
  236.         case 4:  itemType = BASE_ITEM_LIGHTFLAIL; break;
  237.         case 5:  itemType = BASE_ITEM_WARHAMMER; break;
  238.         case 6:  itemType = BASE_ITEM_HEAVYCROSSBOW; break;
  239.         case 7:  itemType = BASE_ITEM_LIGHTCROSSBOW; break;
  240.         case 8:  itemType = BASE_ITEM_LONGBOW; break;
  241.         case 9:  itemType = BASE_ITEM_LIGHTMACE; break;
  242.         case 10: itemType = BASE_ITEM_HALBERD; break;
  243.         case 11: itemType = BASE_ITEM_SHORTBOW; break;
  244.         case 12: itemType = BASE_ITEM_TWOBLADEDSWORD; break;
  245.         case 13: itemType = BASE_ITEM_GREATSWORD; break;
  246.         case 14: itemType = BASE_ITEM_GREATAXE; break;
  247.         case 15: itemType = BASE_ITEM_DAGGER; break;
  248.         case 16: itemType = BASE_ITEM_CLUB; break;
  249.         case 17: itemType = BASE_ITEM_DIREMACE; break;
  250.         case 18: itemType = BASE_ITEM_DOUBLEAXE; break;
  251.         case 19: itemType = BASE_ITEM_HEAVYFLAIL; break;
  252.         case 20: itemType = BASE_ITEM_LIGHTHAMMER; break;
  253.         case 21: itemType = BASE_ITEM_HANDAXE; break;
  254.         case 22: itemType = BASE_ITEM_KAMA; break;
  255.         case 23: itemType = BASE_ITEM_KATANA; break;
  256.         case 24: itemType = BASE_ITEM_KUKRI; break;
  257.         case 25: itemType = BASE_ITEM_MORNINGSTAR; break;
  258.         case 26: itemType = BASE_ITEM_QUARTERSTAFF; break;
  259.         case 27: itemType = BASE_ITEM_RAPIER; break;
  260.         case 28: itemType = BASE_ITEM_SCIMITAR; break;
  261.         case 29: itemType = BASE_ITEM_SCYTHE; break;
  262.         case 30: itemType = BASE_ITEM_SHORTSPEAR; break;
  263.         case 31: itemType = BASE_ITEM_SICKLE; break;
  264.         case 32: itemType = BASE_ITEM_SLING; break;
  265.         case 33: itemType = BASE_ITEM_TRIDENT; break;
  266.         case 34: itemType = BASE_ITEM_DWARVENWARAXE; break;
  267.         case 35: itemType = BASE_ITEM_WHIP; break;
  268.         default: break;
  269.     }
  270.  
  271.     return CreateItemOnObject(getResRefByItemType(itemType), OBJECT_SELF);
  272. }
  273.  
  274. object createArmour()
  275. {
  276.     int itemType = 0;
  277.  
  278.     switch (Random(8))
  279.     {
  280.         case 0:
  281.         case 1:
  282.         case 2:
  283.         case 3:
  284.             itemType = BASE_ITEM_ARMOR;
  285.             break;
  286.  
  287.         case 4:
  288.             itemType = BASE_ITEM_HELMET;
  289.             break;
  290.  
  291.         case 5:
  292.             itemType = BASE_ITEM_SMALLSHIELD;
  293.             break;
  294.  
  295.         case 6:
  296.             itemType = BASE_ITEM_LARGESHIELD;
  297.             break;
  298.  
  299.         case 7:
  300.             itemType = BASE_ITEM_TOWERSHIELD;
  301.             break;
  302.  
  303.         default: break;
  304.     }
  305.  
  306.     return CreateItemOnObject(getResRefByItemType(itemType), OBJECT_SELF);
  307. }
  308.  
  309. object createGear()
  310. {
  311.     int itemType = 0;
  312.  
  313.     switch (Random(8))
  314.     {
  315.         case 0:
  316.             itemType = BASE_ITEM_AMULET;
  317.             break;
  318.  
  319.         case 1:
  320.             itemType = BASE_ITEM_BELT;
  321.             break;
  322.  
  323.         case 2:
  324.             itemType = BASE_ITEM_BRACER;
  325.             break;
  326.  
  327.         case 3:
  328.             itemType = BASE_ITEM_CLOAK;
  329.             break;
  330.  
  331.         case 4:
  332.             itemType = BASE_ITEM_GLOVES;
  333.             break;
  334.  
  335.         case 5:
  336.         case 6:
  337.             itemType = BASE_ITEM_RING;
  338.             break;
  339.  
  340.         case 7:
  341.             itemType = BASE_ITEM_BOOTS;
  342.             break;
  343.  
  344.         default: break;
  345.     }
  346.  
  347.     return CreateItemOnObject(getResRefByItemType(itemType), OBJECT_SELF);
  348. }
  349.  
  350. void applyWeaponStats(object weapon, int ranged)
  351. {
  352.     int propertyCount = Random(MAX_PROPERTY_COUNT) + 1;
  353.  
  354.     int i;
  355.     for (i = 0; i < propertyCount; i++)
  356.     {
  357.         struct PropertyStruct property = getUniqueWeaponProperty(ranged);
  358.         setProperty(i, property);
  359.  
  360.         switch (property.id)
  361.         {
  362.             case WEAPON_ENH_BONUS:
  363.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementBonus(property.mod1), weapon);
  364.                 break;
  365.  
  366.             case WEAPON_AB_BONUS:
  367.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAttackBonus(property.mod1), weapon);
  368.                 break;
  369.  
  370.             case WEAPON_ENH_BONUS_VS_RACE:
  371.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyEnhancementBonusVsRace(property.mod1, property.mod2), weapon);
  372.                 break;
  373.  
  374.             case WEAPON_ELEMENTAL_DAMAGE:
  375.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageBonus(property.mod1, property.mod2), weapon);
  376.                 break;
  377.  
  378.             case WEAPON_ABILITY_BONUS:
  379.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAbilityBonus(property.mod1, property.mod2), weapon);
  380.                 break;
  381.  
  382.             case WEAPON_SKILL_BONUS:
  383.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertySkillBonus(property.mod1, property.mod2), weapon);
  384.                 break;
  385.  
  386.             case WEAPON_MASSIVE_CRITICALS:
  387.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyMassiveCritical(property.mod1), weapon);
  388.                 break;
  389.  
  390.             case WEAPON_MISC_BONUSES:
  391.  
  392.                 switch (property.mod1)
  393.                 {
  394.                     case MISC_BONUS_VISUAL:
  395.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyVisualEffect(property.mod2), weapon);              
  396.                         break;
  397.  
  398.                     case MISC_BONUS_FREEDOM:
  399.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyFreeAction(), weapon);
  400.                         break;
  401.  
  402.                     case MISC_BONUS_FEAR:
  403.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyImmunityMisc(property.mod2), weapon);
  404.                         break;
  405.  
  406.                     case MISC_BONUS_LIGHT:
  407.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLight(property.mod2, Random(7)), weapon);
  408.                         break;
  409.                 }
  410.  
  411.                 break;
  412.  
  413.             case WEAPON_AMMO_OR_VAMP_REGEN:
  414.  
  415.                 if (ranged)
  416.                 {
  417.                     AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyUnlimitedAmmo(property.mod1), weapon);
  418.                 }
  419.                 else
  420.                 {
  421.                     AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyVampiricRegeneration(property.mod1), weapon);
  422.                 }
  423.  
  424.                 break;
  425.  
  426.             case WEAPON_USAGE_RESTRICTION:
  427.  
  428.                 switch (property.mod1)
  429.                 {
  430.                     case USAGE_RESTRICTION_CLASS:
  431.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByClass(property.mod2), weapon);
  432.                         break;
  433.  
  434.                     case USAGE_RESTRICTION_RACE:
  435.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByRace(property.mod2), weapon);
  436.                         break;
  437.                 }
  438.  
  439.                 break;
  440.  
  441.             default: break;
  442.         }
  443.     }  
  444.  
  445.     writePropertiesToLog(propertyCount, ITEM_TYPE_WEAPON);
  446. }
  447.  
  448. void applyArmourStats(object armour)
  449. {
  450.     int propertyCount = Random(MAX_PROPERTY_COUNT) + 1;
  451.  
  452.     int i;
  453.     for (i = 0; i < propertyCount; i++)
  454.     {
  455.         struct PropertyStruct property = getUniqueArmourProperty();
  456.         setProperty(i, property);
  457.  
  458.         switch (property.id)
  459.         {
  460.             case ARMOUR_AC_BONUS:
  461.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonus(property.mod1), armour);
  462.                 break;
  463.  
  464.             case ARMOUR_AC_BONUS_VS_RACE:
  465.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonusVsRace(property.mod1, property.mod2), armour);
  466.                 break;
  467.  
  468.             case ARMOUR_SAVE_BONUS:
  469.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyBonusSavingThrowVsX(property.mod1, property.mod2), armour);
  470.                 break;
  471.  
  472.             case ARMOUR_SPECIFIC_SAVE_BONUS:
  473.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyBonusSavingThrow(property.mod1, property.mod2), armour);
  474.                 break;
  475.  
  476.             case ARMOUR_ELEMENTAL_DR:
  477.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageResistance(property.mod1, property.mod2), armour);
  478.                 break;
  479.  
  480.             case ARMOUR_ABILITY_BONUS:
  481.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAbilityBonus(property.mod1, property.mod2), armour);
  482.                 break;
  483.  
  484.             case ARMOUR_SKILL_BONUS:
  485.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertySkillBonus(property.mod1, property.mod2), armour);
  486.                 break;
  487.  
  488.             case ARMOUR_USAGE_RESTRICTION:
  489.  
  490.                 switch (property.mod1)
  491.                 {
  492.                     case USAGE_RESTRICTION_CLASS:
  493.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByClass(property.mod2), armour);
  494.                         break;
  495.                        
  496.                     case USAGE_RESTRICTION_RACE:
  497.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByRace(property.mod2), armour);
  498.                         break;
  499.                 }
  500.  
  501.                 break;  
  502.  
  503.             default: break;  
  504.         }    
  505.     }
  506.  
  507.     writePropertiesToLog(propertyCount, ITEM_TYPE_ARMOUR);
  508. }
  509.  
  510. void applyGearStats(object gear)
  511. {
  512.     int propertyCount = Random(MAX_PROPERTY_COUNT) + 1;
  513.  
  514.     int i;
  515.     for (i = 0; i < propertyCount; i++)
  516.     {
  517.         struct PropertyStruct property = getUniqueGearProperty();
  518.         setProperty(i, property);
  519.  
  520.         switch (property.id)
  521.         {
  522.             case GEAR_AC_BONUS:
  523.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonus(property.mod1), gear);
  524.                 break;
  525.  
  526.             case GEAR_AC_BONUS_VS_RACE:
  527.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyACBonusVsRace(property.mod1, property.mod2), gear);
  528.                 break;
  529.  
  530.             case GEAR_SAVE_BONUS:
  531.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyBonusSavingThrowVsX(property.mod1, property.mod2), gear);
  532.                 break;
  533.  
  534.             case GEAR_SPECIFIC_SAVE_BONUS:
  535.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyBonusSavingThrow(property.mod1, property.mod2), gear);
  536.                 break;
  537.  
  538.             case GEAR_ELEMENTAL_DR:
  539.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyDamageResistance(property.mod1, property.mod2), gear);
  540.                 break;
  541.  
  542.             case GEAR_ABILITY_BONUS:
  543.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyAbilityBonus(property.mod1, property.mod2), gear);
  544.                 break;
  545.  
  546.             case GEAR_SKILL_BONUS:
  547.                 AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertySkillBonus(property.mod1, property.mod2), gear);
  548.                 break;
  549.  
  550.             case GEAR_USAGE_RESTRICTION:
  551.  
  552.                 switch (property.mod1)
  553.                 {
  554.                     case USAGE_RESTRICTION_CLASS:
  555.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByClass(property.mod2), gear);
  556.                         break;
  557.                        
  558.                     case USAGE_RESTRICTION_RACE:
  559.                         AddItemProperty(DURATION_TYPE_PERMANENT, ItemPropertyLimitUseByRace(property.mod2), gear);
  560.                         break;
  561.                 }
  562.  
  563.                 break;
  564.  
  565.             default: break;      
  566.         }    
  567.     }
  568.  
  569.     writePropertiesToLog(propertyCount, ITEM_TYPE_GEAR);
  570. }
  571.  
  572. void applyDescription(object item)
  573. {
  574.     SetName(item, "Artefact");
  575.     object discoverer = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
  576.     string area = GetSubString(GetName(GetArea(OBJECT_SELF)), 0, FindSubString(GetName(GetArea(OBJECT_SELF)), "(") -1);
  577.     SetDescription(item, "A curious artefact of unknown origin, discovered by " + GetName(discoverer) + " in the " + area + ".");
  578. }
  579.  
  580. struct PropertyStruct getProperty(int index)
  581. {
  582.     struct PropertyStruct property;
  583.  
  584.     if (index >= MAX_PROPERTY_COUNT)
  585.     {
  586.         property.id = 0;
  587.         return property;
  588.     }
  589.  
  590.     struct PropertyVarNameStruct varNames = getPropertyVarNames(index);
  591.     property.id   = GetLocalInt(OBJECT_SELF, varNames.id);
  592.     property.mod1 = GetLocalInt(OBJECT_SELF, varNames.mod1);
  593.     property.mod2 = GetLocalInt(OBJECT_SELF, varNames.mod2);
  594.     return property;
  595. }
  596.  
  597. void setProperty(int index, struct PropertyStruct property)
  598. {
  599.     if (index >= MAX_PROPERTY_COUNT)
  600.     {
  601.         return;
  602.     }
  603.  
  604.     struct PropertyVarNameStruct varNames = getPropertyVarNames(index);
  605.     SetLocalInt(OBJECT_SELF, varNames.id, property.id);
  606.     SetLocalInt(OBJECT_SELF, varNames.mod1, property.mod1);
  607.     SetLocalInt(OBJECT_SELF, varNames.mod2, property.mod2);
  608. }
  609.  
  610. int isPropertyUsed(int property)
  611. {
  612.     int i;
  613.     for (i = 0; i < MAX_PROPERTY_COUNT; ++i)
  614.     {
  615.         if (getProperty(i).id == property)
  616.         {
  617.             return TRUE;
  618.         }
  619.     }
  620.  
  621.     return FALSE;
  622. }
  623.  
  624. struct PropertyStruct findProperty(int propertyId, int nth)
  625. {
  626.     int hit = 0;
  627.     struct PropertyStruct property;
  628.  
  629.     int i;
  630.     for (i = 0; i < MAX_PROPERTY_COUNT; ++i)
  631.     {
  632.         property = getProperty(i);
  633.  
  634.         if (property.id == propertyId)
  635.         {
  636.             if (hit == nth)
  637.             {
  638.                 return property;
  639.             }
  640.             else
  641.             {
  642.                 ++hit;
  643.             }
  644.         }
  645.     }
  646.  
  647.     property.id = INVALID_PROPERTY;
  648.     return property;
  649. }
  650.  
  651. struct PropertyStruct getUniqueWeaponProperty(int ranged)
  652. {
  653.     struct PropertyStruct property;
  654.  
  655.     do
  656.     {
  657.         property.id = Random(WEAPON_PROPERTY_COUNT);
  658.  
  659.         switch (property.id)
  660.         {
  661.             // +1d4 enhancement.
  662.             case WEAPON_ENH_BONUS:
  663.                 // Enhancement bonus.
  664.                 property.mod1 = d4();
  665.                 break;
  666.  
  667.             // +1d4 attack.
  668.             case WEAPON_AB_BONUS:
  669.                 // Attack bonus.
  670.                 property.mod1 = d4();
  671.                 break;
  672.  
  673.             // +1d6 enh vs race.
  674.             case WEAPON_ENH_BONUS_VS_RACE:
  675.                 // Race.
  676.                 property.mod1 = Random(26);
  677.                 // Enhancement bonus.
  678.                 property.mod2 = d6();
  679.                 break;
  680.  
  681.             // +1d10 elemental damage.
  682.             case WEAPON_ELEMENTAL_DAMAGE:
  683.                 // Element.
  684.                 property.mod1 = d8() + 5;
  685.                 // Damage bonus.
  686.                 property.mod2 = d10();
  687.                 break;
  688.  
  689.             // +1d4 to an ability.
  690.             case WEAPON_ABILITY_BONUS:
  691.                 // Ability.
  692.                 property.mod1 = Random(6);
  693.                 // Ability bonus.
  694.                 property.mod2 = d4();
  695.                 break;
  696.  
  697.             // +1d10 to a skill.
  698.             case WEAPON_SKILL_BONUS:
  699.                 // Skill.
  700.                 property.mod1 = Random(28);
  701.                 // Skill bonus.
  702.                 property.mod2 = d10();
  703.                 break;
  704.  
  705.             // +1d10 massive criticals.
  706.             case WEAPON_MASSIVE_CRITICALS:
  707.                 // Massive crit bonus.
  708.                 property.mod1 = d10();
  709.                 break;
  710.  
  711.             // glowy appearance or freedom or fear immunity or light.
  712.             case WEAPON_MISC_BONUSES:
  713.  
  714.                 switch (Random(4))
  715.                 {
  716.                     case MISC_BONUS_VISUAL:
  717.                         // This index.
  718.                         property.mod1 = MISC_BONUS_VISUAL;
  719.                         // Glowy appearance type.
  720.                         property.mod2 = Random(7);            
  721.                         break;
  722.  
  723.                     case MISC_BONUS_FREEDOM:
  724.                         // This index.
  725.                         property.mod1 = MISC_BONUS_FREEDOM;
  726.                         break;
  727.  
  728.                     case MISC_BONUS_FEAR:
  729.                         // This index.
  730.                         property.mod1 = MISC_BONUS_FEAR;
  731.                         // Fear immunity constant.
  732.                         property.mod2 = IP_CONST_IMMUNITYMISC_FEAR;
  733.                         break;
  734.  
  735.                     case MISC_BONUS_LIGHT:
  736.                         // This index.
  737.                         property.mod1 = MISC_BONUS_LIGHT;
  738.                         // Brightness.
  739.                         property.mod2 = d4();
  740.                         break;
  741.                 }
  742.  
  743.                 break;
  744.  
  745.             // unlimited ammo (if ranged) or vamp regen (if not).
  746.             case WEAPON_AMMO_OR_VAMP_REGEN:
  747.  
  748.                 if (ranged)
  749.                 {
  750.                     // Element type.
  751.                     property.mod1 = d3() + 1;
  752.                 }
  753.                 else
  754.                 {
  755.                     // Vamp regen amount.
  756.                     property.mod1 = d6();
  757.                 }
  758.  
  759.                 break;
  760.  
  761.             // usage restriction (class or race).
  762.             case WEAPON_USAGE_RESTRICTION:
  763.  
  764.                 switch (Random(2))
  765.                 {
  766.                     case USAGE_RESTRICTION_CLASS:
  767.                         // This index.
  768.                         property.mod1 = USAGE_RESTRICTION_CLASS;
  769.                         // Which class.
  770.                         property.mod2 = Random(11);
  771.                         break;
  772.  
  773.                     case USAGE_RESTRICTION_RACE:
  774.                         // This index.
  775.                         property.mod1 = USAGE_RESTRICTION_RACE;
  776.                         // Which race.
  777.                         property.mod2 = Random(7);
  778.                         break;
  779.                 }
  780.  
  781.                 break;
  782.  
  783.             default: break;
  784.         }
  785.     } while (!isWeaponPropertyValid(property));
  786.  
  787.  
  788.     return property;
  789. }
  790.  
  791. struct PropertyStruct getUniqueArmourProperty()
  792. {
  793.     struct PropertyStruct property;
  794.  
  795.     do
  796.     {
  797.         property.id = Random(ARMOUR_PROPERTY_COUNT);
  798.  
  799.         switch (property.id)
  800.         {
  801.             // +1d4 AC.
  802.             case ARMOUR_AC_BONUS:
  803.                 // AC bonus.
  804.                 property.mod1 = d4();
  805.                 break;
  806.  
  807.             // +1d6 AC vs race.
  808.             case ARMOUR_AC_BONUS_VS_RACE:
  809.                 // Race.
  810.                 property.mod1 = Random(26);
  811.                 // AC bonus.
  812.                 property.mod2 = d6();
  813.                 break;
  814.  
  815.             // +1d4 save bonus.
  816.             case ARMOUR_SAVE_BONUS:
  817.                 // Uni saves constant.
  818.                 property.mod1 = IP_CONST_SAVEVS_UNIVERSAL;
  819.                 // Save bonus.
  820.                 property.mod2 = d4();
  821.                 break;
  822.  
  823.             // +1d4 specific save bonus.
  824.             case ARMOUR_SPECIFIC_SAVE_BONUS:
  825.                 // Save type.
  826.                 property.mod1 = d3();
  827.                 // Save bonus.
  828.                 property.mod2 = d4();
  829.                 break;
  830.  
  831.             // 5/- to 20/- elemental damage resistance.
  832.             case ARMOUR_ELEMENTAL_DR:
  833.                 // Element.
  834.                 property.mod1 = d8() + 5;
  835.                 // Resistance bonus.
  836.                 property.mod2 = d4();
  837.                 break;
  838.  
  839.             // +1d4 to an ability.
  840.             case ARMOUR_ABILITY_BONUS:
  841.                 // Ability.
  842.                 property.mod1 = Random(6);
  843.                 // Ability bonus.
  844.                 property.mod2 = d4();
  845.                 break;
  846.  
  847.             // +1d10 to a skill.
  848.             case ARMOUR_SKILL_BONUS:
  849.                 // Skill.
  850.                 property.mod1 = Random(28);
  851.                 // Skill bonus.
  852.                 property.mod2 = d10();
  853.                 break;
  854.  
  855.             // usage restriction (class or race).
  856.             case ARMOUR_USAGE_RESTRICTION:
  857.  
  858.                 switch (Random(2))
  859.                 {
  860.                     case USAGE_RESTRICTION_CLASS:
  861.                         // This index.
  862.                         property.mod1 = USAGE_RESTRICTION_CLASS;
  863.                         // Which class.
  864.                         property.mod2 = Random(11);
  865.                         break;
  866.  
  867.                     case USAGE_RESTRICTION_RACE:
  868.                         // This index.
  869.                         property.mod1 = USAGE_RESTRICTION_RACE;
  870.                         // Which race.
  871.                         property.mod2 = Random(7);
  872.                         break;
  873.                 }
  874.  
  875.                 break;  
  876.  
  877.             default: break;    
  878.         }
  879.     } while (!isArmourPropertyValid(property));
  880.  
  881.     return property;
  882. }
  883.  
  884. struct PropertyStruct getUniqueGearProperty()
  885. {
  886.     struct PropertyStruct property;
  887.  
  888.     do
  889.     {
  890.         property.id = Random(GEAR_PROPERTY_COUNT);
  891.  
  892.         switch (property.id)
  893.         {
  894.             // +1d4 AC.
  895.             case ARMOUR_AC_BONUS:
  896.                 // AC bonus.
  897.                 property.mod1 = d4();
  898.                 break;
  899.  
  900.             // +1d6 AC vs race.
  901.             case ARMOUR_AC_BONUS_VS_RACE:
  902.                 // Race.
  903.                 property.mod1 = Random(26);
  904.                 // AC bonus.
  905.                 property.mod2 = d6();
  906.                 break;
  907.  
  908.             // +1d2 save bonus.
  909.             case ARMOUR_SAVE_BONUS:
  910.                 // Uni saves constant.
  911.                 property.mod1 = IP_CONST_SAVEVS_UNIVERSAL;
  912.                 // Save bonus.
  913.                 property.mod2 = d2();
  914.                 break;
  915.  
  916.             // +1d4 specific save bonus.
  917.             case ARMOUR_SPECIFIC_SAVE_BONUS:
  918.                 // Save type.
  919.                 property.mod1 = d3();
  920.                 // Save bonus.
  921.                 property.mod2 = d4();
  922.                 break;
  923.  
  924.             // 5/- to 20/- elemental damage resistance.
  925.             case ARMOUR_ELEMENTAL_DR:
  926.                 // Element.
  927.                 property.mod1 = d8() + 5;
  928.                 // Resistance bonus.
  929.                 property.mod2 = d4();
  930.                 break;
  931.  
  932.             // +1d2 to an ability.
  933.             case ARMOUR_ABILITY_BONUS:
  934.                 // Ability.
  935.                 property.mod1 = Random(6);
  936.                 // Ability bonus.
  937.                 property.mod2 = d2();
  938.                 break;
  939.  
  940.             // +1d6 to a skill.
  941.             case ARMOUR_SKILL_BONUS:
  942.                 // Skill.
  943.                 property.mod1 = Random(28);
  944.                 // Skill bonus.
  945.                 property.mod2 = d6();
  946.                 break;
  947.  
  948.             // usage restriction (class or race).
  949.             case GEAR_USAGE_RESTRICTION:
  950.            
  951.                 switch (Random(2))
  952.                 {
  953.                     case USAGE_RESTRICTION_CLASS:
  954.                         // This index.
  955.                         property.mod1 = USAGE_RESTRICTION_CLASS;
  956.                         // Which class.
  957.                         property.mod2 = Random(11);
  958.                         break;
  959.  
  960.                     case USAGE_RESTRICTION_RACE:
  961.                         // This index.
  962.                         property.mod1 = USAGE_RESTRICTION_RACE;
  963.                         // Which race.
  964.                         property.mod2 = Random(7);
  965.                         break;
  966.                 }
  967.  
  968.                 break;  
  969.  
  970.             default: break;
  971.         }
  972.     } while (!isGearPropertyValid(property));
  973.  
  974.     return property;
  975. }
  976.  
  977. int isWeaponPropertyValid(struct PropertyStruct property)
  978. {
  979.     int i;
  980.     for (i = 0; i < MAX_PROPERTY_COUNT; ++i)
  981.     {
  982.         struct PropertyStruct otherProperty = getProperty(i);
  983.  
  984.         if (property.id == otherProperty.id)
  985.         {
  986.             switch (property.id)
  987.             {
  988.                 case WEAPON_ENH_BONUS: return FALSE;
  989.                 case WEAPON_AB_BONUS: return FALSE;
  990.                 case WEAPON_ENH_BONUS_VS_RACE: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  991.                 case WEAPON_ELEMENTAL_DAMAGE: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  992.                 case WEAPON_ABILITY_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  993.                 case WEAPON_SKILL_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  994.                 case WEAPON_MASSIVE_CRITICALS: return FALSE;
  995.                 case WEAPON_MISC_BONUSES:
  996.  
  997.                     switch (property.mod1)
  998.                     {
  999.                         case MISC_BONUS_VISUAL: return FALSE;
  1000.                         case MISC_BONUS_FREEDOM: return FALSE;
  1001.                         case MISC_BONUS_FEAR: return FALSE;
  1002.                         case MISC_BONUS_LIGHT: return FALSE;
  1003.                     }
  1004.  
  1005.                     break;
  1006.  
  1007.                 case WEAPON_AMMO_OR_VAMP_REGEN: return FALSE;
  1008.                 case WEAPON_USAGE_RESTRICTION:
  1009.  
  1010.                     switch (property.mod1)
  1011.                     {
  1012.                         case USAGE_RESTRICTION_CLASS: if (property.mod2 == otherProperty.mod2) return FALSE; break;
  1013.                         case USAGE_RESTRICTION_RACE: if (property.mod2 == otherProperty.mod2) return FALSE; break;
  1014.                     }
  1015.  
  1016.                     break;
  1017.  
  1018.                 default: break;
  1019.             }
  1020.         }
  1021.  
  1022.         int j;
  1023.         switch (property.id)
  1024.         {
  1025.             case WEAPON_AB_BONUS:
  1026.  
  1027.                 otherProperty = findProperty(WEAPON_ENH_BONUS);
  1028.  
  1029.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1030.                 {
  1031.                     int abBonus = property.mod1;
  1032.                     int enhBonus = otherProperty.mod1;
  1033.  
  1034.                     // Ensure that the ab bonus is greater than any existing enh bonus.
  1035.                     if (!(abBonus > enhBonus))
  1036.                     {
  1037.                         return FALSE;
  1038.                     }
  1039.  
  1040.                     otherProperty = findProperty(WEAPON_ENH_BONUS, j);
  1041.                 }
  1042.  
  1043.                 break;
  1044.  
  1045.             case WEAPON_ENH_BONUS:
  1046.  
  1047.                 otherProperty = findProperty(WEAPON_ENH_BONUS_VS_RACE);
  1048.  
  1049.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1050.                 {
  1051.                     int enhBonus = property.mod1;
  1052.                     int enhBonusVsRace = otherProperty.mod2;
  1053.  
  1054.                     // Ensure that the enh bonus is lower than any existing enh bonus vs race.
  1055.                     if (!(enhBonus < enhBonusVsRace))
  1056.                     {
  1057.                         return FALSE;
  1058.                     }
  1059.  
  1060.                     otherProperty = findProperty(WEAPON_ENH_BONUS_VS_RACE, j);
  1061.                 }
  1062.  
  1063.                 break;
  1064.  
  1065.             case WEAPON_ENH_BONUS_VS_RACE:
  1066.  
  1067.                 otherProperty = findProperty(WEAPON_ENH_BONUS);
  1068.  
  1069.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1070.                 {
  1071.                     int enhBonus = otherProperty.mod1;
  1072.                     int enhBonusVsRace = property.mod2;
  1073.  
  1074.                     // Ensure that the specific bonus vs race is higher than the existing enh bonus.
  1075.                     if (!(enhBonusVsRace > enhBonus))
  1076.                     {
  1077.                         return FALSE;
  1078.                     }
  1079.  
  1080.                     otherProperty = findProperty(WEAPON_ENH_BONUS, j);
  1081.                 }
  1082.  
  1083.                 break;
  1084.  
  1085.  
  1086.             default: break;
  1087.         }
  1088.     }
  1089.  
  1090.     return TRUE;
  1091. }
  1092.  
  1093. int isArmourPropertyValid(struct PropertyStruct property)
  1094. {
  1095.     int i;
  1096.     for (i = 0; i < MAX_PROPERTY_COUNT; ++i)
  1097.     {
  1098.         struct PropertyStruct otherProperty = getProperty(i);
  1099.  
  1100.         if (property.id == otherProperty.id)
  1101.         {
  1102.             switch (property.id)
  1103.             {
  1104.                 case ARMOUR_AC_BONUS: return FALSE;
  1105.                 case ARMOUR_AC_BONUS_VS_RACE: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1106.                 case ARMOUR_SAVE_BONUS: return FALSE;
  1107.                 case ARMOUR_SPECIFIC_SAVE_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1108.                 case ARMOUR_ELEMENTAL_DR: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1109.                 case ARMOUR_ABILITY_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1110.                 case ARMOUR_SKILL_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1111.                 case ARMOUR_USAGE_RESTRICTION:
  1112.  
  1113.                     switch (property.mod1)
  1114.                     {
  1115.                         case USAGE_RESTRICTION_CLASS: if (property.mod2 == otherProperty.mod2) return FALSE; break;
  1116.                         case USAGE_RESTRICTION_RACE: if (property.mod2 == otherProperty.mod2) return FALSE; break;
  1117.                     }
  1118.  
  1119.                     break;  
  1120.  
  1121.                 default: break;
  1122.             }
  1123.         }
  1124.  
  1125.         int j;
  1126.         switch (property.id)
  1127.         {
  1128.             case ARMOUR_AC_BONUS:
  1129.  
  1130.                 otherProperty = findProperty(ARMOUR_AC_BONUS_VS_RACE);
  1131.  
  1132.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1133.                 {
  1134.                     int acBonus = property.mod1;
  1135.                     int acBonusVsRace = otherProperty.mod2;
  1136.  
  1137.                     // Ensure that the AC bonus is less than any existing AC bonus vs race.
  1138.                     if (!(acBonus < acBonusVsRace))
  1139.                     {
  1140.                         return FALSE;
  1141.                     }
  1142.  
  1143.                     otherProperty = findProperty(ARMOUR_AC_BONUS_VS_RACE, j);
  1144.                 }
  1145.  
  1146.                 break;
  1147.  
  1148.             case ARMOUR_AC_BONUS_VS_RACE:
  1149.        
  1150.                 otherProperty = findProperty(ARMOUR_AC_BONUS);
  1151.  
  1152.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1153.                 {
  1154.                     int acBonus = otherProperty.mod1;
  1155.                     int acBonusVsRace = property.mod2;
  1156.  
  1157.                     // Ensure that the AC bonus vs race is greater than any existing AC bonus.
  1158.                     if (!(acBonusVsRace > acBonus))
  1159.                     {
  1160.                         return FALSE;
  1161.                     }
  1162.  
  1163.                     otherProperty = findProperty(ARMOUR_AC_BONUS, j);
  1164.                 }
  1165.  
  1166.                 break;
  1167.        
  1168.             case ARMOUR_SAVE_BONUS:
  1169.        
  1170.                 otherProperty = findProperty(ARMOUR_SPECIFIC_SAVE_BONUS);
  1171.  
  1172.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1173.                 {
  1174.                     int uniSave = property.mod2;
  1175.                     int specificSave = otherProperty.mod2;
  1176.  
  1177.                     // Ensure that the uni save is less than any existing specific saves.
  1178.                     if (!(uniSave < specificSave))
  1179.                     {
  1180.                         return FALSE;
  1181.                     }
  1182.                    
  1183.                     otherProperty = findProperty(ARMOUR_SPECIFIC_SAVE_BONUS, j);
  1184.                 }
  1185.  
  1186.                 break;
  1187.        
  1188.             case ARMOUR_SPECIFIC_SAVE_BONUS:
  1189.        
  1190.                 otherProperty = findProperty(ARMOUR_SAVE_BONUS);
  1191.  
  1192.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1193.                 {
  1194.                     int uniSave = otherProperty.mod2;
  1195.                     int specificSave = property.mod2;
  1196.  
  1197.                     // Ensure that the specific save is greater than any existing uni save.
  1198.                     if (!(specificSave > uniSave))
  1199.                     {
  1200.                         return FALSE;
  1201.                     }
  1202.                    
  1203.                     otherProperty = findProperty(ARMOUR_SAVE_BONUS, j);
  1204.                 }
  1205.  
  1206.                 break;
  1207.  
  1208.             default: break;
  1209.         }
  1210.     }
  1211.  
  1212.     return TRUE;
  1213. }
  1214.  
  1215. int isGearPropertyValid(struct PropertyStruct property)
  1216. {
  1217.     int i;
  1218.     for (i = 0; i < MAX_PROPERTY_COUNT; ++i)
  1219.     {
  1220.         struct PropertyStruct otherProperty = getProperty(i);
  1221.  
  1222.         if (property.id == otherProperty.id)
  1223.         {
  1224.             switch (property.id)
  1225.             {
  1226.                 case GEAR_AC_BONUS: return FALSE;
  1227.                 case GEAR_AC_BONUS_VS_RACE: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1228.                 case GEAR_SAVE_BONUS: return FALSE;
  1229.                 case GEAR_SPECIFIC_SAVE_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1230.                 case GEAR_ELEMENTAL_DR: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1231.                 case GEAR_ABILITY_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1232.                 case GEAR_SKILL_BONUS: if (property.mod1 == otherProperty.mod1) return FALSE; break;
  1233.                 case GEAR_USAGE_RESTRICTION:
  1234.  
  1235.                     switch (property.mod1)
  1236.                     {
  1237.                         case USAGE_RESTRICTION_CLASS: if (property.mod2 == otherProperty.mod2) return FALSE; break;
  1238.                         case USAGE_RESTRICTION_RACE: if (property.mod2 == otherProperty.mod2) return FALSE; break;
  1239.                     }
  1240.  
  1241.                     break;
  1242.  
  1243.                 default: break;
  1244.             }
  1245.         }
  1246.  
  1247.         int j;
  1248.         switch (property.id)
  1249.         {
  1250.             case GEAR_AC_BONUS:
  1251.  
  1252.                 otherProperty = findProperty(GEAR_AC_BONUS_VS_RACE);
  1253.  
  1254.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1255.                 {
  1256.                     int acBonus = property.mod1;
  1257.                     int acBonusVsRace = otherProperty.mod2;
  1258.  
  1259.                     // Ensure that the AC bonus is less than any existing AC bonus vs race.
  1260.                     if (!(acBonus < acBonusVsRace))
  1261.                     {
  1262.                         return FALSE;
  1263.                     }
  1264.  
  1265.                     otherProperty = findProperty(GEAR_AC_BONUS_VS_RACE, j);
  1266.                 }
  1267.  
  1268.                 break;
  1269.  
  1270.             case GEAR_AC_BONUS_VS_RACE:
  1271.        
  1272.                 otherProperty = findProperty(GEAR_AC_BONUS);
  1273.  
  1274.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1275.                 {
  1276.                     int acBonus = otherProperty.mod1;
  1277.                     int acBonusVsRace = property.mod2;
  1278.  
  1279.                     // Ensure that the AC bonus vs race is greater than any existing AC bonux.
  1280.                     if (!(acBonusVsRace > acBonus))
  1281.                     {
  1282.                         return FALSE;
  1283.                     }
  1284.  
  1285.                     otherProperty = findProperty(GEAR_AC_BONUS, j);
  1286.                 }
  1287.  
  1288.                 break;
  1289.        
  1290.             case GEAR_SAVE_BONUS:
  1291.        
  1292.                 otherProperty = findProperty(GEAR_SPECIFIC_SAVE_BONUS);
  1293.  
  1294.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1295.                 {
  1296.                     int uniSave = property.mod2;
  1297.                     int specificSave = otherProperty.mod2;
  1298.  
  1299.                     // Ensure that the uni save is less than any existing specific saves.
  1300.                     if (!(uniSave < specificSave))
  1301.                     {
  1302.                         return FALSE;
  1303.                     }
  1304.                    
  1305.                     otherProperty = findProperty(GEAR_SPECIFIC_SAVE_BONUS, j);
  1306.                 }
  1307.  
  1308.                 break;
  1309.        
  1310.             case GEAR_SPECIFIC_SAVE_BONUS:
  1311.        
  1312.                 otherProperty = findProperty(GEAR_SAVE_BONUS);
  1313.  
  1314.                 for (j = 0; otherProperty.id != INVALID_PROPERTY; ++j)
  1315.                 {
  1316.                     int uniSave = otherProperty.mod2;
  1317.                     int specificSave = property.mod2;
  1318.  
  1319.                     // Ensure that the specific save is greater than any existing uni save.
  1320.                     if (!(specificSave > uniSave))
  1321.                     {
  1322.                         return FALSE;
  1323.                     }
  1324.                    
  1325.                     otherProperty = findProperty(GEAR_SAVE_BONUS, j);
  1326.                 }
  1327.  
  1328.                 break;
  1329.  
  1330.             default: break;
  1331.         }
  1332.     }
  1333.  
  1334.     return TRUE;
  1335. }
  1336.  
  1337. void cleanupPropertyVars()
  1338. {
  1339.     int i;
  1340.     for (i = 0; i < MAX_PROPERTY_COUNT; ++i)
  1341.     {
  1342.         struct PropertyVarNameStruct varNames = getPropertyVarNames(i);
  1343.         SetLocalInt(OBJECT_SELF, varNames.id, INVALID_PROPERTY);
  1344.         SetLocalInt(OBJECT_SELF, varNames.mod1, INVALID_PROPERTY);
  1345.         SetLocalInt(OBJECT_SELF, varNames.mod2, INVALID_PROPERTY);
  1346.     }
  1347. }
  1348.  
  1349. struct PropertyVarNameStruct getPropertyVarNames(int index)
  1350. {
  1351.     string propertyArrBase = "PROPERTY_ARR_" + IntToString(index);
  1352.     struct PropertyVarNameStruct varNames;
  1353.     varNames.id   = propertyArrBase + "_ID";
  1354.     varNames.mod1 = propertyArrBase + "_MOD1";
  1355.     varNames.mod2 = propertyArrBase + "_MOD2";
  1356.     return varNames;
  1357. }
  1358.  
  1359. void writePropertiesToLog(int propertyCount, int itemType)
  1360. {
  1361.     object nearestPlayer = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
  1362.     string logOutput = "Generated item type " + IntToString(itemType) + " " +
  1363.                        "in " + GetTag(GetArea(OBJECT_SELF)) + " " +
  1364.                        "by " + GetName(nearestPlayer) + " " +
  1365.                        "[" + GetPCPublicCDKey(nearestPlayer) + "] " +
  1366.                        "with property Count: " + IntToString(propertyCount) + " ( ";
  1367.  
  1368.     int i;
  1369.     for (i = 0; i < propertyCount; ++i)
  1370.     {
  1371.         struct PropertyStruct property = getProperty(i);
  1372.         logOutput += "Property " + IntToString(i) + ": [" +
  1373.                      "id=" + IntToString(property.id) + ", " +
  1374.                      "mod1=" + IntToString(property.mod1) + ", " +
  1375.                      "mod2=" + IntToString(property.mod2) + "] ";
  1376.     }
  1377.  
  1378.     Log("ARTIFACT", logOutput + ")");
  1379. }
  1380.  
  1381. string getResRefByItemType(int itemType)
  1382. {
  1383.     switch (itemType)
  1384.     {
  1385.         case BASE_ITEM_AMULET:         return "gs_item209";
  1386.  
  1387.         case BASE_ITEM_ARMOR:
  1388.         {
  1389.             switch (Random(4))
  1390.             {
  1391.                 case 0:                return "nw_cloth027";
  1392.                 case 1:                return "nw_aarcl001";
  1393.                 case 2:                return "nw_aarcl003";
  1394.                 case 3:                return "nw_aarcl007";
  1395.             }
  1396.         }
  1397.  
  1398.         case BASE_ITEM_BASTARDSWORD:   return "nw_wswbs001";
  1399.         case BASE_ITEM_BATTLEAXE:      return "nw_waxbt001";
  1400.         case BASE_ITEM_BELT:           return "gs_item258";
  1401.         case BASE_ITEM_BOOTS:          return "gs_item311";
  1402.         case BASE_ITEM_BRACER:         return "gs_item270";
  1403.         case BASE_ITEM_CLOAK:          return "gs_item284";
  1404.         case BASE_ITEM_CLUB:           return "nw_wblcl001";
  1405.         case BASE_ITEM_DAGGER:         return "nw_wswdg001";
  1406.         case BASE_ITEM_DIREMACE:       return "nw_wdbma001";
  1407.         case BASE_ITEM_DOUBLEAXE:      return "nw_wdbax001";
  1408.         case BASE_ITEM_DWARVENWARAXE:  return "x2_wdwraxe001";
  1409.         case BASE_ITEM_GLOVES:         return "gs_item294";
  1410.         case BASE_ITEM_GREATAXE:       return "nw_waxgr001";
  1411.         case BASE_ITEM_GREATSWORD:     return "nw_wswgs001";
  1412.         case BASE_ITEM_HALBERD:        return "nw_wplhb001";
  1413.         case BASE_ITEM_HANDAXE:        return "nw_waxhn001";
  1414.         case BASE_ITEM_HEAVYCROSSBOW:  return "nw_wbwxh001";
  1415.         case BASE_ITEM_HEAVYFLAIL:     return "nw_wblfh001";
  1416.         case BASE_ITEM_HELMET:         return "x2_it_arhelm03";
  1417.         case BASE_ITEM_KAMA:           return "nw_wspka001";
  1418.         case BASE_ITEM_KATANA:         return "nw_wswka001";
  1419.         case BASE_ITEM_KUKRI:          return "nw_wspku001";
  1420.         case BASE_ITEM_LARGESHIELD:    return "nw_ashlw001";
  1421.         case BASE_ITEM_LIGHTCROSSBOW:  return "nw_wbwxl001";
  1422.         case BASE_ITEM_LIGHTFLAIL:     return "nw_wblfl001";
  1423.         case BASE_ITEM_LIGHTHAMMER:    return "nw_wblhl001";
  1424.         case BASE_ITEM_LIGHTMACE:      return "nw_wblml001";
  1425.         case BASE_ITEM_LONGBOW:        return "nw_wbwln001";
  1426.         case BASE_ITEM_LONGSWORD:      return "nw_wswls001";
  1427.         case BASE_ITEM_MORNINGSTAR:    return "nw_wblms001";
  1428.         case BASE_ITEM_QUARTERSTAFF:   return "nw_wdbqs001";
  1429.         case BASE_ITEM_RAPIER:         return "nw_wswrp001";
  1430.         case BASE_ITEM_RING:           return "gs_item252";
  1431.         case BASE_ITEM_SCIMITAR:       return "nw_wswsc001";
  1432.         case BASE_ITEM_SCYTHE:         return "nw_wplsc001";
  1433.         case BASE_ITEM_SHORTBOW:       return "nw_wbwsh001";
  1434.         case BASE_ITEM_SHORTSPEAR:     return "nw_wplss001";
  1435.         case BASE_ITEM_SHORTSWORD:     return "nw_wswss001";
  1436.         case BASE_ITEM_SICKLE:         return "nw_wspsc001";
  1437.         case BASE_ITEM_SLING:          return "nw_wbwsl001";
  1438.         case BASE_ITEM_SMALLSHIELD:    return "nw_ashsw001";
  1439.         case BASE_ITEM_TOWERSHIELD:    return "nw_ashto001";
  1440.         case BASE_ITEM_TRIDENT:        return "nw_wpltr001";
  1441.         case BASE_ITEM_TWOBLADEDSWORD: return "nw_wdbsw001";
  1442.         case BASE_ITEM_WARHAMMER:      return "nw_wblhw001";
  1443.         case BASE_ITEM_WHIP:           return "x2_it_wpwhip";
  1444.         default:                       break;
  1445.     }
  1446.  
  1447.     return "";
  1448. }
clone this paste RAW Paste Data