pluginrepairing.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. class PluginRepairing extends PluginBase
  2. {
  3. bool Repair(PlayerBase player, ItemBase repair_kit, Object item, float specialty_weight, string damage_zone = "", bool use_kit_qty = true)
  4. {
  5. switch (item.GetHealthLevel(damage_zone))
  6. {
  7. case GameConstants.STATE_PRISTINE:
  8. break;
  9. case GameConstants.STATE_RUINED:
  10. #ifdef DEVELOPER
  11. Debug.Log("repairing from GameConstants.STATE_RUINED");
  12. #endif
  13. CalculateHealth(player, repair_kit, item, specialty_weight, damage_zone, use_kit_qty);
  14. break;
  15. case GameConstants.STATE_WORN:
  16. if (CanRepairToPristine(player) || CanBeRepairedToPristine(item))
  17. {
  18. CalculateHealth(player, repair_kit, item, specialty_weight,/* GameConstants.DAMAGE_PRISTINE_VALUE,*/ damage_zone, use_kit_qty);
  19. }
  20. break;
  21. default:
  22. CalculateHealth(player, repair_kit, item, specialty_weight, damage_zone, use_kit_qty);
  23. break;
  24. }
  25. return true;
  26. }
  27. void CalculateHealth(PlayerBase player, ItemBase kit, Object item, float specialty_weight, string damage_zone = "", bool use_kit_qty = true)
  28. {
  29. EntityAI entity;
  30. Class.CastTo(entity,item);
  31. if (entity != null)
  32. {
  33. entity.SetAllowDamage(true);
  34. }
  35. int health_levels_count = item.GetNumberOfHealthLevels(damage_zone);
  36. float kit_repair_cost_adjusted; //used with specialty_weight, disconnected
  37. float new_quantity;
  38. int target_level = Math.Clamp(item.GetHealthLevel(damage_zone) - 1, 0, health_levels_count - 1);
  39. float health_coef;
  40. if (!CanRepairToPristine(player) && !CanBeRepairedToPristine(item))
  41. {
  42. target_level = Math.Clamp(target_level, GameConstants.STATE_WORN, health_levels_count - 1);
  43. }
  44. health_coef = item.GetHealthLevelValue(target_level,damage_zone);
  45. //handles kit depletion; TODO: move to separate method.
  46. if (kit && kit.ConfigGetInt("repairKitType"))
  47. {
  48. bool kit_has_quantity = kit.HasQuantity();
  49. float cur_kit_quantity = kit.GetQuantity();
  50. float kit_repair_cost_per_level = GetKitRepairCost(kit, item);
  51. if (cur_kit_quantity > kit_repair_cost_per_level)
  52. {
  53. kit_repair_cost_adjusted = kit_repair_cost_per_level; //TODO: removed speciality weight for now, it should affect speed only (?).
  54. //kit_repair_cost_adjusted = player.GetSoftSkillsManager().SubtractSpecialtyBonus(kit_repair_cost_per_level, specialty_weight);
  55. kit_repair_cost_adjusted = Math.Clamp(kit_repair_cost_adjusted, 0, 100);
  56. if (use_kit_qty)
  57. {
  58. new_quantity = kit.GetQuantity() - kit_repair_cost_adjusted;
  59. kit.SetQuantity(new_quantity);
  60. }
  61. }
  62. else if (!kit_has_quantity) //"kit" without quantity (hammers and such) for your every day repairing needs
  63. {
  64. }
  65. else
  66. {
  67. if (use_kit_qty)
  68. {
  69. kit.SetQuantity(0);
  70. }
  71. }
  72. }
  73. if (item.GetHealth01(damage_zone,"Health") < health_coef)
  74. {
  75. item.SetHealth01(damage_zone,"Health",health_coef);
  76. }
  77. if (entity != null)
  78. {
  79. entity.ProcessInvulnerabilityCheck(entity.GetInvulnerabilityTypeString());
  80. }
  81. }
  82. bool CanRepair(ItemBase repair_kit, Object item, string damage_zone = "")
  83. {
  84. int state = item.GetHealthLevel(damage_zone);
  85. if (state != GameConstants.STATE_RUINED && (item.CanBeRepairedToPristine() && state >= GameConstants.STATE_WORN) || (!item.CanBeRepairedToPristine() && state >= GameConstants.STATE_DAMAGED))
  86. {
  87. int repair_kit_type = repair_kit.ConfigGetInt("repairKitType");
  88. if (!repair_kit_type) //outside of regular repair kit logic for some reason, bypass check
  89. {
  90. return true;
  91. }
  92. array<int> repairable_with_types = new array<int>;
  93. item.ConfigGetIntArray("repairableWithKits", repairable_with_types);
  94. for (int i = 0; i < repairable_with_types.Count(); i++)
  95. {
  96. int repairable_with_type = repairable_with_types.Get(i);
  97. if (IsRepairValid(repair_kit_type, repairable_with_type))
  98. {
  99. return true;
  100. }
  101. }
  102. }
  103. return false;
  104. }
  105. private bool IsRepairValid(int repair_kit_type, int repairable_with_type)
  106. {
  107. if (repair_kit_type > 0 && repairable_with_type > 0)
  108. {
  109. return repair_kit_type == repairable_with_type;
  110. }
  111. return false;
  112. }
  113. //! Player can repair items to 100%; currently unused
  114. private bool CanRepairToPristine(PlayerBase player)
  115. {
  116. return false;
  117. }
  118. //! Item can be repaired to 100%
  119. private bool CanBeRepairedToPristine(Object item)
  120. {
  121. return item.CanBeRepairedToPristine();
  122. }
  123. private float GetKitRepairCost(ItemBase repair_kit, Object item)
  124. {
  125. array<int> allowedRepairKitTypes = new array<int>();
  126. array<float> repairKitCosts = new array<float>();
  127. item.ConfigGetIntArray("repairableWithKits", allowedRepairKitTypes);
  128. item.ConfigGetFloatArray("repairCosts", repairKitCosts);
  129. int repairKitType = repair_kit.ConfigGetInt("repairKitType");
  130. foreach (int i, int allowedKitType : allowedRepairKitTypes)
  131. {
  132. if (allowedKitType == repairKitType)
  133. {
  134. return repairKitCosts.Get(i);
  135. }
  136. }
  137. return 0;
  138. }
  139. }