notfff 7 maanden geleden
bovenliggende
commit
a7e5436edd

+ 3 - 3
app/Module/GameItems/AdminControllers/ItemController.php

@@ -296,9 +296,9 @@ class ItemController extends AdminController
             $form->switch('is_unique', '单独属性')
                 ->default(false);
             $form->number('max_stack', '最大堆叠')
-                ->default(1)
-                ->min(1)
-                ->help('0表示无限堆叠');
+                ->default(0)
+                ->min(0)
+                ->help('0表示无限堆叠,大于0表示限制堆叠数量');
             $form->number('sell_price', '出售价格')
                 ->default(0)
                 ->min(0);

+ 1 - 1
app/Module/GameItems/Databases/GenerateSql/item_items.sql

@@ -11,7 +11,7 @@ CREATE TABLE `kku_item_items` (
   `category_id` int NOT NULL COMMENT '物品分类ID,外键关联kku_item_categories表',
   `type` tinyint NOT NULL COMMENT '物品类型(1:可使用, 2:可装备, 3:可合成, 4:可交任务, 5:可开启...)',
   `is_unique` tinyint DEFAULT '0' COMMENT '是否是单独属性物品(0:否,默认, 1:是)',
-  `max_stack` int DEFAULT '1' COMMENT '最大堆叠数量',
+  `max_stack` int DEFAULT '0' COMMENT '最大堆叠数量(0表示无限堆叠)',
   `sell_price` int DEFAULT '0' COMMENT '出售价格',
   `tradable` tinyint DEFAULT '1' COMMENT '是否可交易(0:不可交易, 1:可交易,默认)',
   `dismantlable` tinyint DEFAULT '1' COMMENT '是否可分解(0:不可分解, 1:可分解,默认)',

+ 46 - 19
app/Module/GameItems/Logics/Item.php

@@ -45,7 +45,13 @@ class Item
             return false;
         }
 
-        return $item->global_expire_at->isPast();
+        // 确保 global_expire_at 是 Carbon 实例
+        $expireAt = $item->global_expire_at;
+        if (is_string($expireAt)) {
+            $expireAt = \Carbon\Carbon::parse($expireAt);
+        }
+
+        return $expireAt->isPast();
     }
 
     /**
@@ -78,7 +84,7 @@ class Item
         // 开始事务
         DB::beginTransaction();
         try {
-            // 检查用户是否已有该物品且过期时间相同
+            // 检查用户是否已有该物品且过期时间相同,并且未满堆叠
             $userItem = ItemUser::where('user_id', $userId)
                 ->where('item_id', $itemId)
                 ->where(function ($query) use ($expireAt) {
@@ -89,6 +95,12 @@ class Item
                     }
                 })
                 ->whereNull('instance_id')
+                ->where(function ($query) use ($item) {
+                    // 如果有最大堆叠限制,只查找未满的堆叠
+                    if ($item->max_stack > 0) {
+                        $query->where('quantity', '<', $item->max_stack);
+                    }
+                })
                 ->first();
 
             $addedQuantity = $quantity;
@@ -101,17 +113,29 @@ class Item
 
                 // 检查最大堆叠限制
                 if ($item->max_stack > 0 && $newQuantity > $item->max_stack) {
-                    // 超过最大堆叠,创建新堆叠
+                    // 超过最大堆叠,先填满当前堆叠
+                    $canAddToCurrent = $item->max_stack - $currentQuantity;
                     $userItem->quantity = $item->max_stack;
                     $userItem->save();
 
-                    // 剩余数量
-                    $remainingQuantity = $newQuantity - $item->max_stack;
+                    // 触发物品数量变更事件(更新现有堆叠)
+                    Event::dispatch(new ItemQuantityChanged(
+                        $userId,
+                        $itemId,
+                        null,
+                        $currentQuantity,
+                        $item->max_stack,
+                        $userItem->id,
+                        $options
+                    ));
 
-                    // 递归添加剩余数量
-                    self::addNormalItem($userId, $itemId, $remainingQuantity, $options);
+                    // 剩余数量递归添加到新堆叠
+                    $remainingQuantity = $quantity - $canAddToCurrent;
+                    if ($remainingQuantity > 0) {
+                        self::addNormalItem($userId, $itemId, $remainingQuantity, $options);
+                    }
 
-                    $addedQuantity = $quantity - $remainingQuantity;
+                    $addedQuantity = $quantity;
                     $currentQuantity = $item->max_stack;
                 } else {
                     // 未超过最大堆叠,直接更新数量
@@ -133,33 +157,36 @@ class Item
                 }
             } else {
                 // 没有该物品,创建新记录
+                $createQuantity = min($quantity, $item->max_stack > 0 ? $item->max_stack : $quantity);
                 $userItem = new ItemUser([
                     'user_id' => $userId,
                     'item_id' => $itemId,
-                    'quantity' => min($quantity, $item->max_stack > 0 ? $item->max_stack : $quantity),
+                    'quantity' => $createQuantity,
                     'expire_at' => $expireAt,
                 ]);
                 $userItem->save();
 
-                // 如果数量超过最大堆叠,递归添加剩余数量
-                if ($item->max_stack > 0 && $quantity > $item->max_stack) {
-                    $remainingQuantity = $quantity - $item->max_stack;
-                    self::addNormalItem($userId, $itemId, $remainingQuantity, $options);
-                    $addedQuantity = $item->max_stack;
-                }
-
-                $currentQuantity = $userItem->quantity;
-
                 // 触发物品数量变更事件(新增物品)
                 Event::dispatch(new ItemQuantityChanged(
                     $userId,
                     $itemId,
                     null,
                     0, // 旧数量为0
-                    $currentQuantity,
+                    $createQuantity,
                     $userItem->id,
                     $options
                 ));
+
+                // 如果数量超过最大堆叠,递归添加剩余数量
+                if ($item->max_stack > 0 && $quantity > $item->max_stack) {
+                    $remainingQuantity = $quantity - $item->max_stack;
+                    self::addNormalItem($userId, $itemId, $remainingQuantity, $options);
+                    $addedQuantity = $quantity; // 总添加数量
+                } else {
+                    $addedQuantity = $createQuantity;
+                }
+
+                $currentQuantity = $createQuantity;
             }
 
             // 记录交易日志

+ 5 - 2
app/Module/GameItems/Models/Item.php

@@ -10,7 +10,7 @@ use UCore\ModelCore;
 /**
  * 物品基础信息
  *
- * field start 
+ * field start
  * @property  int  $id  物品ID,主键
  * @property  string  $name  物品名称
  * @property  string  $description  物品描述
@@ -39,7 +39,7 @@ class Item extends ModelCore
      */
     protected $table = 'item_items';
 
-    // attrlist start 
+    // attrlist start
     protected $fillable = [
         'id',
         'name',
@@ -79,6 +79,9 @@ class Item extends ModelCore
         'numeric_attributes' => \App\Module\GameItems\Casts\NumericAttributesCast::class,
         'type'               => ITEM_TYPE::class,
         'is_unique'          => 'boolean',
+        'max_stack'          => 'integer',
+        'sell_price'         => 'integer',
+        'default_expire_seconds' => 'integer',
         'tradable'           => 'boolean',
         'dismantlable'       => 'boolean',
     ];