#　クラス



class Action
	attr_accessor :actor, :targets
	def initialize(actor, targets = nil)
		@actor = actor
		@targets = targets
		@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
		return 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
	
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
		return "攻撃"
	end
end

class RanpageAction < AttackAction

	def get_effect
		return RanpageEffect.new
	end
	

	def base_message_text
		@actor.weapon.get_ranpage_message
	end


	
	def caption
		return "猛襲"
	end
	
	def unguarding?
		return true
	end
	
	def speed
		super + 5
	end


end

class SmashAction < AttackAction

	def get_effect
		return SmashEffect.new
	end
	

	def base_message_text
		@actor.weapon.get_smash_message
	end


	
	def caption
		return "強打"
	end
	
	def unguarding?
		return true
	end

end


class FeintAction < AttackAction

	def get_effect
		return FeintEffect.new
	end
	

	def base_message_text
		_('%{actor}はフェイントをかけた！')
	end
	
	def caption
		return "フェイント"
	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
		"チャージ(#{@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
		return "身を守る"
	end

end

class BlockAction < DelayedAction
	
	def caption
		return "ブロック"
	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
		rate = (@actor.magic_boost? ? 2 : 1)
		cost = self.trick_data.mp_cost * rate
		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
