#　クラス


module DarkHall
	class Action
		attr_accessor :actor, :targets
		def initialize(actor, targets = nil)
			@actor = actor
			@targets = targets
			if @targets and not @targets.kind_of?(Array) then
				@targets = [@targets]
			end
			@random_speed_bonus = rand(6)
		end
		
		# メッセージのでないアクションかどうか
		def silent?
			false
		end
		
		# 盾が使えるアクションかどうか
		def unguarding?
			false
		end
		
		# 行動速度
		def speed
			@actor.speed
		end
		
		# 実際に行動順の計算に用いる速度値（ランダム補正がかかる）
		def real_speed
			self.speed + @random_speed_bonus
		end
		
		def get_effect
			nil
		end
		
		def target
			return(@targets ? @targets.first : nil)
		end
	
		def target_name
			if @targets and not @targets.empty? then
				Util.targets_caption(@targets)
			end
		end
	
		def targets_alive?
			if @targets then
				# ターゲットが生存しているかどうか
				alives = @targets.compact.find_all{|x| x.alive?}
				return !(alives.empty?)
			else
				return true
			end
		end
	
	
		
		
		def base_message_params
			re = {:actor => @actor.name}
			re[:target] = target_name
			re[:party] = GS.party.name
			
			re
		end
	
		
		def base_message_text
			nil
		end
		
		def get_base_message
			if base_message_text then
				text = Util.eval_text(base_message_text, base_message_params)
				return Message.new(text)
			else
				nil
			end
		end
		
		# MPやアイテム消失などのコスト処理。消費できない場合にはfalse（強制キャンセル）
		def pay_cost
			true
		end
		
		
	
		def operate
			#$member_index = GS.party.members.index(@actor) if actor.kind_of?(Member)
			LOGGER.puts "#{@actor.name} - #{self.caption}"
	
			# 対象が見つからない場合
			if @targets and not targets_alive? then
				LOGGER.puts "<対象が見つからないためキャンセルされました>"
				return nil
			end
			
			# 死亡している・もしくは動けない場合
			unless @actor.active? then
				LOGGER.puts "<行動者が動けないためキャンセルされました>"
				return nil
			end
			
			
			if pay_cost then
				effect = get_effect
				if effect then
					msg = effect.operate(@actor, @targets, get_base_message)
					if silent? then
						msg = nil
					end
				else
					msg = nil
				end
				
				on_effect_operated
				return msg
	
			else
				LOGGER.puts "<コストが支払えないためキャンセルされました>"
				return nil
			end
			
			return nil
		end
	
		def on_effect_operated
		end
		
		def to_error_report_model
			re = {}
			re['class'] = self.class.to_s
			re['actor'] = @actor.type_caption
			if @targets then
				if @targets.kind_of?(Array) then
					re['targets'] = targets.map{|x| (x.respond_to?(:type_caption) ? x.type_caption : x.class.to_s)}
				else
					re['targets'] = @targets.class.to_s
				end
			end
			re['speed'] = speed
			if @actor.dead? then
				re['actor_dead'] = true
			end
			unless @actor.status.empty? then
				re['actor_status'] = @actor.status.map{|x| (x.respond_to?(:type_caption) ? x.type_caption : x.class.to_s)}
			end
			
			re
		end
		
	end
	
	class QuickAction < Action
		def speed
			999
		end
	end
	
	class DelayedAction < Action
		def speed
			-999
		end
		
		def real_speed
			-999
		end
	
	end
	
	
	class AttackAction < Action
	
		def unguarding?
			(@actor.weapon && @actor.weapon.double_handed)
		end
	
		def base_message_text
			if @actor.find_state(HidingState) then
				@actor.weapon.get_sneak_attack_message
			else
				@actor.weapon.get_attack_message
			end
		end
	
		
		def get_effect
			WeaponAttackEffect.new
		end
		
		
	
		
		def caption
			_("攻撃")
		end
		
		def pay_cost
			# 武器を持ってなければキャンセル
			(@actor.weapon ? super : false) 
		end
	end
	
	class RanpageAction < AttackAction
	
		def get_effect
			RanpageEffect.new
		end
		
	
		def base_message_text
			@actor.weapon.get_ranpage_message
		end
	
		
		def caption
			_("猛襲")
		end
		
		def unguarding?
			return true
		end
		
		def speed
			super + 5
		end
	end
	
	class DoubleRanpageAction < RanpageAction
		def get_effect
			DoubleRanpageEffect.new
		end
	end
	
	class SmashAction < AttackAction
	
		def get_effect
			return SmashEffect.new
		end
		
	
		def base_message_text
			@actor.weapon.get_smash_message
		end
	
	
		
		def caption
			_("強打")
		end
		
		def unguarding?
			return true
		end
	end
	
	class CounterAttackAction < AttackAction
	
		def get_effect
			CounterAttackEffect.new
		end
		
	
		def base_message_text
			@actor.weapon.get_smash_message
		end
		
		def speed
			999
		end
		
		def caption
			_("カウンター")
		end
	end
	
	class SharpAttackAction < AttackAction
		def initialize(actor, attack_targets, ability_type)
			super(actor, attack_targets)
			@ability_type = ability_type
		end
		
		
		def get_effect
			SharpAttackEffect.new(@ability_type)
		end
		
	
		def base_message_text
			@actor.weapon.get_sharp_attack_message
		end
	
	
		
		def caption
			_("精密打撃")
		end
		
		def unguarding?
			true
		end
	end


	
	
	class FeintAction < AttackAction
	
		def get_effect
			return FeintEffect.new
		end
		
	
		def base_message_text
			_('%{actor}はフェイントをかけた！')
		end
		
		def caption
			_("フェイント")
		end
		
		def speed
			super + 5
		end
	
	end
	
	
	
	
	class HideAction < QuickAction
		def caption
			_("隠れる")
		end
		
		def initialize(actor)
			super(actor, [actor])
		end
	
		
		def base_message_text
			_('%{actor}はすばやく身を隠した')
		end
		
		def get_effect
			return RecoverEffect.new({
				:add_state_data => [[HidingState, 1]],
			})
		end
	
	end
	
	
	class ChargingAction < QuickAction
		def caption
			_("チャージ(%{level})").evaluate(:level => @charging_level)
		end
		
		def initialize(actor, attack_targets, charging_level)
			super(actor, [actor])
			@charging_level = charging_level
			@attack_targets = attack_targets
		end
		
		def base_message_text
			_('%{actor}は弓を強く引き絞った……')
		end
		
		def get_effect
			return RecoverEffect.new({
				:add_state_data => [[ChargingState, @charging_level, @attack_targets]],
			})
		end
	
	end
	
	class ReleaseArrowAction < AttackAction
		def initialize(actor, targets, charging_level)
			super(actor, targets)
			@charging_level = charging_level
		end
	
		def get_effect
			return ChargeAttackEffect.new(@charging_level)
		end
	
	end
	
	class PrayAction < QuickAction
		
		def caption
			_("祈る")
		end
		
		def base_message_text
			_("%{actor}は祭具を取り出し、精霊たちに祈りはじめた……\n%{party}は呪文攻撃と呪いに対する保護を得た")
		end
		
		def silent?
			$battle.praying
		end
		
		def on_effect_operated
			$battle.praying = true
		end
		
		def get_effect
			re = PartyEnhanceEffect.new
			re.state_data = [[ElementalProtectionState, 1]]
			
			re
		end
	
	end
	
	
	class GuardAction < DelayedAction
		
		def caption
			_("身を守る")
		end
	
	end
	
	class BlockAction < DelayedAction
		
		def caption
			_("ブロック")
		end
	
	end
	
	
	class ItemUseAction < Action
		attr_accessor :item
		def initialize(actor, targets, item)
			super(actor, targets)
			@item = item
		end
		
		def get_effect
			@item.effect
		end
		
		def base_message_params
			re = super
			re[:actor] = @actor.name
			re[:target] = target_name
			re[:item] = @item.name
			
			re
		end
		
		def base_message_text
			if @item.message_type then
				if @targets == [@actor] then
					return DB.pick_item_message(@item.message_type, false)
				else
					return DB.pick_item_message(@item.message_type, true)
				end
			else
				return nil
			end
		end
	
		
		
		def pay_cost
			if @item.instant then
				index = @actor.items.index(@item)
				@actor.lose_item(index)
				LOGGER.puts "#{@item.name}を消費 (index=#{index})"
			end
			
			return true
	
		end
		
		def caption
			@item.name
		end
		
		def speed
			sp = @actor.speed - 5
			sp += 8 if @actor.kind_of?(Explorer)
			return sp
		end
		
		def on_effect_operated
			@actor.remove_state(HidingState)
		end
	end
	
	
	class SpellCastAction < Action
		
		attr_accessor :spell_id
		def initialize(actor, targets, trick_symbol)
			super(actor, targets)
			@trick_symbol = trick_symbol
			case self.trick_data.target_type
			when TG_MEMBER
				@against = false
			end
		end
		
		def speed
			re = @actor.speed - 5
			re += 30 if @actor.find_state(CastingAccelerationState)
			
			re
		end
		
		def spell_data
			SPELL_DATA[trick_data.spell_id]
		end
		
		def trick_data
			TRICK_DATA[@trick_symbol]
		end
		
		def base_message_text
			list = trick_data.messages
			Util.random_pick(list)
		end
		
		def base_message_params
			re = super
			re[:spell] = spell_data.name
			re[:trick] = trick_data.name
			
			re
		end
	
	
		
		
		def unguarding?
			return true
		end
		
	
	
		
		def pay_cost
			cost = self.trick_data.mp_cost
			cost -= @actor.mp_cost_reducing
			cost *= 2 if @actor.magic_boost?
			LOGGER.puts "消費MP: #{cost}"
			if @actor.mp[trick_data.spell_id] >= cost then
				@actor.use_mp(cost, trick_data.spell_id)
				
				return true
			else
				return false
			end
		end
	
	
		def get_effect
			return(@actor.magic_boost? ? trick_data.boost_effect : trick_data.effect)
		end
		
		def caption
			trick_data.name
		end
		
	end
	
	class SpecialAction < Action
		attr_accessor :model_id
		def initialize(actor, targets, model_id)
			super(actor, targets)
			@model_id = model_id
		end
	
		def model
			DB.find_special_action(@model_id)
		end
		
		def get_effect
			model.effect
		end
		
		def speed
			@actor.speed + model.speed_bonus
		end
		
		def caption
			@model_id
		end
		
		
		
	end
end