ItemChestContent.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace App\Module\GameItems\Models;
  3. use Illuminate\Database\Eloquent\Relations\BelongsTo;
  4. use Illuminate\Database\Eloquent\Relations\HasMany;
  5. use UCore\ModelCore;
  6. /**
  7. * 宝箱内容配置
  8. *
  9. * field start
  10. * @property int $id 记录ID,主键
  11. * @property int $chest_id 宝箱物品ID,外键关联kku_item_items表
  12. * @property int $item_id 可能获得的物品ID,外键关联kku_item_items表(与group_id二选一)
  13. * @property int $group_id 物品组ID,外键关联kku_item_groups表(与item_id二选一)
  14. * @property int $min_quantity 最小数量
  15. * @property int $max_quantity 最大数量
  16. * @property float $weight 权重,决定获取概率
  17. * @property int $allow_duplicate 是否允许在同一宝箱中重复掉落(0:不允许, 1:允许)
  18. * @property int $pity_count 保底次数,当玩家连续未获得该内容达到次数后必定获得(0表示不启用保底)
  19. * @property float $pity_weight_factor 保底权重因子,用于递增概率计算(默认1.0)
  20. * @property \Carbon\Carbon $created_at 创建时间
  21. * @property \Carbon\Carbon $updated_at 更新时间
  22. * field end
  23. */
  24. class ItemChestContent extends ModelCore
  25. {
  26. /**
  27. * 与模型关联的表名
  28. *
  29. * @var string
  30. */
  31. protected $table = 'item_chest_contents';
  32. // attrlist start
  33. protected $fillable = [
  34. 'id',
  35. 'chest_id',
  36. 'item_id',
  37. 'group_id',
  38. 'min_quantity',
  39. 'max_quantity',
  40. 'weight',
  41. 'allow_duplicate',
  42. 'pity_count',
  43. 'pity_weight_factor',
  44. ];
  45. // attrlist end
  46. /**
  47. * 应该被转换为原生类型的属性
  48. *
  49. * @var array
  50. */
  51. protected $casts = [
  52. 'weight' => 'float',
  53. 'min_quantity' => 'integer',
  54. 'max_quantity' => 'integer',
  55. 'allow_duplicate' => 'boolean',
  56. 'pity_count' => 'integer',
  57. 'pity_weight_factor' => 'float',
  58. ];
  59. /**
  60. * 获取关联的宝箱物品
  61. *
  62. * @return BelongsTo
  63. */
  64. public function chest(): BelongsTo
  65. {
  66. return $this->belongsTo(ItemItem::class, 'chest_id');
  67. }
  68. /**
  69. * 获取关联的物品(如果有)
  70. *
  71. * @return BelongsTo
  72. */
  73. public function item(): BelongsTo
  74. {
  75. return $this->belongsTo(ItemItem::class, 'item_id');
  76. }
  77. /**
  78. * 获取关联的物品组(如果有)
  79. *
  80. * @return BelongsTo
  81. */
  82. public function group(): BelongsTo
  83. {
  84. return $this->belongsTo(ItemGroup::class, 'group_id');
  85. }
  86. /**
  87. * 获取用户对该宝箱内容的保底计数
  88. *
  89. * @return HasMany
  90. */
  91. public function pityTimes(): HasMany
  92. {
  93. return $this->hasMany(ItemPityTime::class, 'chest_content_id');
  94. }
  95. /**
  96. * 判断是否为物品组内容
  97. *
  98. * @return bool
  99. */
  100. public function isGroupContent(): bool
  101. {
  102. return !empty($this->group_id);
  103. }
  104. /**
  105. * 获取随机数量
  106. *
  107. * @return int
  108. */
  109. public function getRandomQuantity(): int
  110. {
  111. if ($this->min_quantity == $this->max_quantity) {
  112. return $this->min_quantity;
  113. }
  114. return mt_rand($this->min_quantity, $this->max_quantity);
  115. }
  116. /**
  117. * 计算调整后的权重(考虑保底机制)
  118. *
  119. * @param int $currentPityCount 当前保底计数
  120. * @return float
  121. */
  122. public function getAdjustedWeight(int $currentPityCount = 0): float
  123. {
  124. if (empty($this->pity_count) || $currentPityCount <= 0) {
  125. return $this->weight;
  126. }
  127. // 如果达到保底次数,返回极大值确保必定获得
  128. if ($currentPityCount >= $this->pity_count) {
  129. return 999999.999;
  130. }
  131. // 计算权重调整因子
  132. $pityFactor = ($currentPityCount / $this->pity_count) * $this->pity_weight_factor;
  133. // 返回调整后的权重
  134. return $this->weight * (1 + $pityFactor);
  135. }
  136. }