Project1

标题: 问一个物品掉落的算法…… [打印本页]

作者: saturnfjh    时间: 2010-10-6 16:29
标题: 问一个物品掉落的算法……
本帖最后由 saturnfjh 于 2010-10-25 10:28 编辑

先奉上原脚本《掉落扩张》:
  1. #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
  2. #_/    ◆ ドロップアイテム拡張 - KGC_ExtraDropItem ◆ VX ◆
  3. #_/    ◇ Last update : 2008/08/28 ◇
  4. #_/----------------------------------------------------------------------------
  5. #_/  敵が落とすアイテムの種類を増やします。
  6. #_/============================================================================
  7. #_/ 【特殊システム】≪戦闘難易度≫ より上に導入してください。
  8. #_/ 【メニュー】≪モンスター図鑑≫ より下に導入してください。
  9. #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

  10. $imported = {} if $imported == nil
  11. $imported["ExtraDropItem"] = true

  12. module KGC
  13. module ExtraDropItem
  14.   # 正規表現
  15.   module Regexp
  16.     # エネミー
  17.     module Enemy
  18.       # ドロップアイテム
  19.       DROP_ITEM = /<(?:DROP|ドロップ)\s*([IWA]):(\d+)\s+(\d+)([%%])?>/i
  20.     end
  21.   end
  22. end
  23. end

  24. #★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

  25. #==============================================================================
  26. # ■ RPG::Enemy
  27. #==============================================================================

  28. class RPG::Enemy
  29.   #--------------------------------------------------------------------------
  30.   # ○ ドロップアイテム拡張のキャッシュ生成
  31.   #--------------------------------------------------------------------------
  32.   def create_extra_drop_item_cache
  33.     @__extra_drop_items = []

  34.     self.note.each_line { |line|
  35.       case line
  36.       when KGC::ExtraDropItem::Regexp::Enemy::DROP_ITEM
  37.         # ドロップアイテム
  38.         item = RPG::Enemy::DropItem.new
  39.         case $1.upcase
  40.         when "I"  # アイテム
  41.           item.kind = 1
  42.           item.item_id = $2.to_i
  43.         when "W"  # 武器
  44.           item.kind = 2
  45.           item.weapon_id = $2.to_i
  46.         when "A"  # 防具
  47.           item.kind = 3
  48.           item.armor_id = $2.to_i
  49.         else
  50.           next
  51.         end
  52.         # ドロップ率
  53.         if $4 != nil
  54.           item.drop_prob = $3.to_i
  55.         else
  56.           item.denominator = $3.to_i
  57.         end
  58.         @__extra_drop_items << item
  59.       end
  60.     }
  61.   end
  62.   #--------------------------------------------------------------------------
  63.   # ○ 拡張ドロップアイテム
  64.   #--------------------------------------------------------------------------
  65.   def extra_drop_items
  66.     create_extra_drop_item_cache if @__extra_drop_items == nil
  67.     return @__extra_drop_items
  68.   end
  69. end

  70. #★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

  71. #==============================================================================
  72. # ■ RPG::Enemy::DropItem
  73. #==============================================================================

  74. unless $@
  75. class RPG::Enemy::DropItem
  76.   #--------------------------------------------------------------------------
  77.   # ● 公開インスタンス変数
  78.   #--------------------------------------------------------------------------
  79.   attr_writer   :drop_prob                # ドロップ率
  80.   #--------------------------------------------------------------------------
  81.   # ○ ドロップ率取得
  82.   #--------------------------------------------------------------------------
  83.   def drop_prob
  84.     @drop_prob = 0 if @drop_prob == nil
  85.     return @drop_prob
  86.   end
  87. end
  88. end

  89. #★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

  90. #==============================================================================
  91. # ■ Game_Enemy
  92. #==============================================================================

  93. class Game_Enemy < Game_Battler
  94.   #--------------------------------------------------------------------------
  95.   # ○ 拡張ドロップアイテムの取得
  96.   #--------------------------------------------------------------------------
  97.   def extra_drop_items
  98.     return enemy.extra_drop_items
  99.   end
  100. end

  101. #★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★

  102. #==============================================================================
  103. # ■ Game_Troop
  104. #==============================================================================

  105. class Game_Troop < Game_Unit
  106.   #--------------------------------------------------------------------------
  107.   # ● ドロップアイテムの配列作成
  108.   #--------------------------------------------------------------------------
  109.   alias make_drop_items_KGC_ExtraDropItem make_drop_items
  110.   def make_drop_items
  111.     drop_items = make_drop_items_KGC_ExtraDropItem

  112.     dead_members.each { |enemy|
  113.       enemy.extra_drop_items.each_with_index { |di, i|
  114.         next if di.kind == 0
  115.         if di.drop_prob > 0
  116.           # 確率指定
  117.           next if di.drop_prob < rand(100)
  118.             
  119.         else
  120.           # 分母指定
  121.           next if rand(di.denominator) != 0
  122.         end
  123.         if di.kind == 1
  124.           drop_items.push($data_items[di.item_id])
  125.         elsif di.kind == 2
  126.           drop_items.push($data_weapons[di.weapon_id])
  127.         elsif di.kind == 3
  128.           drop_items.push($data_armors[di.armor_id])
  129.         end
  130.         # ドロップ済みフラグをセット
  131.         if $imported["EnemyGuide"]
  132.           KGC::Commands.set_enemy_item_dropped(enemy.enemy.id, i + 2)
  133.         end
  134.       }
  135.     }
  136.     return drop_items
  137.   end
  138. end
复制代码
问题如下:
现在我想修改一下物品掉落的算法,不再一个一个物品判断,而是从N件物品中选取X件掉落:
设想如下:
STEP1 利用以上脚本读取掉落列表中的各物品掉落率
STEP2 加总掉落率总和,以此判断掉落件数,例如,总和T满足:T<100则掉落一件,100<T<200则掉落2件……以此类推
STEP3 从掉落列表中用rand(T)函数获取第1件掉落
STEP4 从掉落列表中用rand(T)函数获取第2件掉落(如果有的话),与第1件相同则重复此步骤
STEP5 从掉落列表中用rand(T)函数获取第3件掉落(如果有的话),与第1、2件相同则重复此步骤
STEP6 ...
FINAL STEP 确定掉落

以上算法要用脚本应该怎么写?替换原脚本哪一节?我刚接触脚本不久,对于里面一些函数的用法不熟悉,想请高手指点一二;另,有没有更优的算法?

作者: saturnfjh    时间: 2010-10-6 21:25
自顶……求大师指点一二啊……我不是伸手党,只是不知道怎么写这个算法。。555。。
作者: saturnfjh    时间: 2010-10-7 21:20
再顶……豁出去了……求指点……
作者: summer92    时间: 2010-10-8 10:59
提示:自己写算法,有时候不要死钻一点
作者: saturnfjh    时间: 2010-10-10 17:08
回复 summer92 的帖子
=。= 现在就是找不到更好地算法才来求救的。。
关键是我不太熟悉脚本的循环。。

   
作者: saturnfjh    时间: 2010-10-12 20:22
自顶。。。求安慰。。
作者: 禾西    时间: 2010-10-13 09:57
make_drop_items是關鍵
作用就是讀取物品 push 進 drop_items 這個數組

作者: saturnfjh    时间: 2010-10-14 20:51
  1. class Game_Troop < Game_Unit
  2.   #--------------------------------------------------------------------------
  3.   # ● ドロップアイテムの配列作成
  4.   #--------------------------------------------------------------------------
  5.   alias make_drop_items_KGC_ExtraDropItem make_drop_items
  6.   def make_drop_items
  7.     drop_items = make_drop_items_KGC_ExtraDropItem
  8.     drop_count = 0
  9.     drop_piece = 0
  10.     drop_make = 0
  11.     drop_price = 0
  12.     dead_members.each { |enemy|
  13.       enemy.extra_drop_items.each_with_index { |di, i|
  14.         drop_count += i
  15.     next if di.kind == 0
  16.     #判断掉落件数
  17.     if drop_count <= 100
  18.       drop_piece = drop_count > rand(100)? 1:0
  19.     elsif drop_count <= 200
  20.       drop_piece = drop_count > rand(200)? 2:1
  21.     else
  22.       drop_piece = drop_count > rand(300)? 3:2
  23.     end
  24.     #根据件数判断物品
  25.     case drop_piece
  26.     when 0
  27.       return
  28.     when 1
  29.       drop_price = rand(100)
  30.       enemy.extra_drop_items.each_with_index { |di, i|
  31.       drop_make += i
  32.       next if drop_make < drop_price
  33.         if di.kind == 1
  34.           drop_items.push($data_items[di.item_id])
  35.         elsif di.kind == 2
  36.           drop_items.push($data_weapons[di.weapon_id])
  37.         elsif di.kind == 3
  38.           drop_items.push($data_armors[di.armor_id])
  39.         end
  40.       }
  41.     when 2
  42.       for a in 1..2
  43.         drop_price = rand(200)
  44.         enemy.extra_drop_items.each_with_index { |di, i|
  45.         drop_make += i
  46.         next if drop_make < drop_price
  47.           if di.kind == 1
  48.             drop_items.push($data_items[di.item_id])
  49.           elsif di.kind == 2
  50.             drop_items.push($data_weapons[di.weapon_id])
  51.           elsif di.kind == 3
  52.             drop_items.push($data_armors[di.armor_id])
  53.           end
  54.       }
  55.         next
  56.       end
  57.     when 3
  58.       for a in 1..3
  59.         drop_price = rand(300)
  60.         enemy.extra_drop_items.each_with_index { |di, i|
  61.         drop_make += i
  62.         next if drop_make < drop_price
  63.           if di.kind == 1
  64.             drop_items.push($data_items[di.item_id])
  65.           elsif di.kind == 2
  66.             drop_items.push($data_weapons[di.weapon_id])
  67.           elsif di.kind == 3
  68.             drop_items.push($data_armors[di.armor_id])
  69.           end
  70.       }
  71.         next
  72.       end
  73.     end
  74.         if $imported["EnemyGuide"]
  75.           KGC::Commands.set_enemy_item_dropped(enemy.enemy.id, i + 2)
  76.         end
  77.       }
  78.     }
  79.     return drop_items
  80.   end
  81. end
复制代码
我照着改了一下,然后出现 未定义 each 方法,请各位大师指点一下要怎么修改。。
作者: saturnfjh    时间: 2010-10-15 17:02
自顶。。求安慰。。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1