LUA实现状态模式

G_DynamicNPCs_Talking_Fun = {}
API_AddLUAReqFunc("GDynamicNpcsTalk")
function GDynamicNpcsTalk()
	local playerID 	= API_RequestGetActorID()
	local TalkID	= API_RequestGetString(1)
	local Index		= API_RequestGetNumber(2)
	local UID 		= API_RequestGetNumber(3)
	if nil ~= G_DynamicNPCs_Talking_Fun[TalkID] then
		G_DynamicNPCs_Talking_Fun[TalkID][Index](playerID, UID)
	end
	return 10
end
--仿照windows的CD机制, 可以在CD上不断用begin和end重画每一帧,begin会清掉上次的, 当消除CD时也会消除掉数据。
function GDynamicNpcsTalkManage()
	local public = {}
	function public.newTalkItems(_playerID, _NpcUID)
		local TalkID = "" .. _playerID .. "|" .. _NpcUID
		myPrint("TalkID " .. TalkID, 1)
		G_DynamicNPCs_Talking_Fun[TalkID] = {}
		local talkPublic = {}
		local iCount = 0
		local szCaption
		function talkPublic.Begin(_szCaption)
			szCaption = _szCaption
			iCount = 0
		end
		function talkPublic.AddItem(_szItemText, _Fun, _bClose)
			local Index = table.getn(G_DynamicNPCs_Talking_Fun[TalkID]) + 1
			G_DynamicNPCs_Talking_Fun[TalkID][ Index ] = _Fun
			if _bClose then
				API_ResponseWrite(ChuanSongStr..'<a size="13" color="175,216,242" closewindow = "1" href="GDynamicNpcsTalk?1='.. TalkID .. '&2='.. Index .. '&3='.. _NpcUID .. '">' .. _szItemText .. '</a><br>')
			else
				API_ResponseWrite(ChuanSongStr..'<a size="13" color="175,216,242" href="GDynamicNpcsTalk?1='.. TalkID .. '&2='.. Index .. '&3='.. _NpcUID .. '">' .. _szItemText .. '</a><br>')
			end
			iCount = iCount + 1
		end
		function talkPublic.End()
			if 0 == iCount then
				API_OpenWindow(_playerID,WndID_TaskDialog,0)
			else
				API_ResponseWrite('<name>'.. szCaption ..'</name>')
				API_ResponseFlush(_playerID)
			end
		end
		function talkPublic.Delete()
			G_DynamicNPCs_Talking_Fun[TalkID] = nil
		end
		return talkPublic
	end
	return public
end
G_DynamicNPCsTalking_Manager = GDynamicNpcsTalkManage()


 

 

--修改了IGoodsActions文件
--待策划东西配好, 需改回来

G_TREE_OBJ = {}
function UpdataTreeTaskData(_par1, _par2)
	if nil ~= G_TREE_OBJ[_par1] then
		G_TREE_OBJ[_par1].delete()
		G_TREE_OBJ[_par1] = nil
	end
	local tgrID = API_GetCurTriggerID()
	API_DestroyTriggerG(tgrID)
end


function newTreeNpc(_MapID, _x, _y, _dir, _RoleID)
	local ID_PAIR = {{11387, 11388}, {11387, 11389}, {11387, 11390}, {11387, 11391}}
	local treenpc_public = { CUR_ID = math.random(1, table.getn(ID_PAIR))}
	local G_TREE_OBJ_ID = nil
	for i=1, 99999 do
		if nil == G_TREE_OBJ[i] then
			G_TREE_OBJ_ID = i
			G_TREE_OBJ[G_TREE_OBJ_ID] = treenpc_public
			break
		end
	end
	if nil == G_TREE_OBJ_ID then
		myPrint("newTreeNpc 资源耗尽",1)
		return
	end
	local tgrID = API_CreateTimerTriggerG(G_TREE_OBJ_ID, 0, 250, 1, "UpdataTreeTaskData")

	--树基础状态
	function newTreeState()
		local tState ={}
		function tState.InState()
			myPrint("种树状态的进入未实现!", 1)
		end
		function tState.OutState()
			myPrint("种树状态的退出未实现!", 1)
		end
		function tState.OnOpenNPCWindows(_playerID, _pTaskID)
			myPrint("种树状态未实现!", 1)
		end
		return tState
	end

	--虚状态
	function newVirtualState()
		local curState = nil
		local tState = newTreeState()
		function tState.SetState(_pState)
			if nil ~= curState then
				curState.OutState()
			end
			curState = _pState
			if nil == curState then
				curState = newTreeState()
			end
			curState.InState()
		end
		function tState.GetState()
			return curState
		end
		function tState.InState()
		end
		function tState.OutState()
			curState.OutState()
		end
		function tState.OnOpenNPCWindows(_playerID, _pTaskID)
			curState.OnOpenNPCWindows(_playerID, _pTaskID)
		end
		return tState
	end
	treenpc_public.virState = newVirtualState()
	function treenpc_public.TryTransition()
		if treenpc_public.virState.GetState() == treenpc_public.tDevelopingTree then
			if treenpc_public.tDevelopingTree.getLack() <= 0 then
				treenpc_public.virState.SetState(treenpc_public.tDevelopedTree)
				treenpc_public.virState.OnOpenNPCWindows(_RoleID, 0)
			end
		end
	end

	--成长状态
	function newDevelopingTree()
		local tPrivate = {}
		local tDevelopingTree = newTreeState()
		local tTreeNpc = nil
		local tTalkItems = nil
		local tPar = nil
		--进入状态
		function tDevelopingTree.InState()
			myPrint("种下树!", 1)
			tPar = {Lack = 10, TIMES_MAX = 10, ITEM1_Count = 0, ITEM2_Count = 0, ITEM3_Count = 0}
			tTreeNpc = G_DynamicNPCs.obj_CreateSob(ID_PAIR[treenpc_public.CUR_ID][1], _MapID, _x, _y, _dir)
			tTalkItems = G_DynamicNPCsTalking_Manager.newTalkItems(_RoleID, tTreeNpc.UID)
			local TIMES_LIFT = tPar.TIMES_MAX - 3
			local a = math.random(0,TIMES_LIFT)
			local b = math.random(0,TIMES_LIFT - a)
			local c = TIMES_LIFT - a - b
			tPar.ITEM1_Count = 1 + a
			tPar.ITEM2_Count = 1 + b
			tPar.ITEM3_Count = 1 + c

			--选项1
			function tPrivate.Item1()
				local function OverProcess(_playerID, _UserSign1, _UserSign2)
					tPar.Lack = tPar.Lack - 2
					API_ActorSendMsg(_playerID, 2, "目前树苗不满度" .. tPar.Lack)
					treenpc_public.TryTransition()
				end
				local function On(_playerID, _UID)
					if G_ProcessBar_Manager.CreateProcessBar(_RoleID, 1, OverProcess) then
						API_ActorSendMsg(_RoleID, 2, "进行使用金钱增加阳光")
						tPar.ITEM1_Count = tPar.ITEM1_Count - 1
						treenpc_public.virState.OnOpenNPCWindows(_RoleID, 0)
					else
						API_ActorSendMsg(_RoleID, 2, "操作进行中")
					end
				end
				return On
			end

			--选项2
			function tPrivate.Item2()
				local function OverProcess(_playerID, _UserSign1, _UserSign2)
					tPar.Lack = tPar.Lack - 2
					API_ActorSendMsg(_RoleID, 2, "目前树苗不满度" .. tPar.Lack)
					treenpc_public.TryTransition()
				end
				local function On(_playerID, _UID)
					if G_ProcessBar_Manager.CreateProcessBar(_RoleID, 1, OverProcess) then
						API_ActorSendMsg(_RoleID, 2, "进行使用吟唱消灭虫子")
						tPar.ITEM2_Count = tPar.ITEM2_Count - 1
						treenpc_public.virState.OnOpenNPCWindows(_RoleID, 0)
					else
						API_ActorSendMsg(_RoleID, 2, "操作进行中")
					end
				end
				return On
			end

			--选项3
			function tPrivate.Item3()
				local function OverProcess(_playerID, _UserSign1, _UserSign2)
					tPar.Lack = tPar.Lack - 2
					API_ActorSendMsg(_RoleID, 2, "目前树苗不满度" .. tPar.Lack)
					treenpc_public.TryTransition()
				end
				local function On(_playerID, _UID)
					local BOX_ID = 4001
					if API_ActorGetGoodsNum(_RoleID, BOX_ID) > 0 then
						API_ActorRemoveGoods(_RoleID, BOX_ID, 1, "种树消耗一件道具")
					else
						API_ActorSendMsg(_RoleID, 2, "没有种树道具: " .. BOX_ID)
						return
					end
					if G_ProcessBar_Manager.CreateProcessBar(_RoleID, 1, OverProcess) then
						API_ActorSendMsg(_RoleID, 2, "进行使用商城道具施肥")
						tPar.ITEM3_Count = tPar.ITEM3_Count - 1
						treenpc_public.virState.OnOpenNPCWindows(_RoleID, 0)
					else
						API_ActorSendMsg(_RoleID, 2, "操作进行中")
					end
				end
				return On
			end

			--开窗函数
			function tTreeNpc.OnOpenNPCWindows(_playerID, _pTaskID)
				tTalkItems.Begin("" .. _playerID .. "|" .. G_TREE_OBJ_ID)
				--myPrint("发展状态", 1)
				if _playerID == _RoleID then
					if tPar.ITEM1_Count > 0 then
						tTalkItems.AddItem("使用金钱增加阳光(" .. tPar.ITEM1_Count .. ")", tPrivate.Item1(), false)
					end
					if tPar.ITEM2_Count > 0 then
						tTalkItems.AddItem("使用吟唱消灭虫子(" .. tPar.ITEM2_Count .. ")", tPrivate.Item2(), false)
					end
					if tPar.ITEM3_Count > 0 then
						tTalkItems.AddItem("使用商城道具施肥(" .. tPar.ITEM3_Count .. ")" , tPrivate.Item3(), false)
					end
				end
				tTalkItems.End()
				return 10
			end


		end

		--退出状态
		function tDevelopingTree.OutState()
			myPrint("树离开发展态!", 1)
			tTalkItems.Delete()
			G_DynamicNPCs.DeleteSob(tTreeNpc.ID, tTreeNpc.UID)
			G_ProcessBar_Manager.DeleteProcessBar(_RoleID)
		end

		--获得不足值
		function tDevelopingTree.getLack()
			return tPar.Lack
		end

		--开窗
		function tDevelopingTree.OnOpenNPCWindows(_playerID, _pTaskID)
			return tTreeNpc.OnOpenNPCWindows(_playerID, _pTaskID)
		end

		return tDevelopingTree
	end
	treenpc_public.tDevelopingTree = newDevelopingTree()




	--成熟状态
	function newDevelopedTree()
		local tPrivate = {}
		local tDevelopedTree = newTreeState()
		local tTreeNpc = nil
		local tTalkItems = nil
		local tPar = nil
		--进入状态
		function tDevelopedTree.InState()
			myPrint("树成熟!", 1)
			tPar = {ITEM1_Count = 10}
			tTreeNpc = G_DynamicNPCs.obj_CreateSob(ID_PAIR[treenpc_public.CUR_ID][2], _MapID, _x, _y, _dir)
			tTalkItems = G_DynamicNPCsTalking_Manager.newTalkItems(_RoleID, tTreeNpc.UID)

			--选项1
			function tPrivate.Item1()
				local function On(_playerID, _UID)
					tPar.ITEM1_Count = tPar.ITEM1_Count - 1
					API_ActorSendMsg(_playerID, 2, "果实剩余数" .. tPar.ITEM1_Count)
					treenpc_public.virState.OnOpenNPCWindows(_RoleID, 0)
				end
				return On
			end

			--开窗函数
			function tTreeNpc.OnOpenNPCWindows(_playerID, _pTaskID)
				tTalkItems.Begin("" .. _playerID .. "|" .. G_TREE_OBJ_ID)
				--myPrint("成熟状态", 1)
				if _playerID == _RoleID then
					if tPar.ITEM1_Count > 0 then
						tTalkItems.AddItem("采摘果实", tPrivate.Item1(), false)
					end
				end
				tTalkItems.End()
				return 10
			end

			local BOX_ID = 1000004
			if API_ActorCanAddGoodsEx(_RoleID, "" .. BOX_ID, "" .. 1, 0, 0) then
				API_AddActorGoods(_RoleID, BOX_ID, 1, "种树奖")
				API_ActorSendMsg(_RoleID, 2, "获得种树奖励")
			else
				API_SendActorMail(_RoleID, BOX_ID, 1, "种树奖", "种树奖")
				API_ActorSendMsg(_RoleID, 2, "由于背包已满,种树奖已寄到您的邮箱")
			end
		end

		--退出状态
		function tDevelopedTree.OutState()
			myPrint("树枯萎!", 1)
			tTalkItems.Delete()
			G_DynamicNPCs.DeleteSob(tTreeNpc.ID, tTreeNpc.UID)
			G_ProcessBar_Manager.DeleteProcessBar(_RoleID)
		end

		--获得不足值
		function tDevelopedTree.getLack()
			return tPar.Lack
		end

		--开窗
		function tDevelopedTree.OnOpenNPCWindows(_playerID, _pTaskID)
			return tTreeNpc.OnOpenNPCWindows(_playerID, _pTaskID)
		end

		return tDevelopedTree
	end
	treenpc_public.tDevelopedTree = newDevelopedTree()



	treenpc_public.virState.SetState(treenpc_public.tDevelopingTree)
	function treenpc_public.delete()
		treenpc_public.virState.OutState()
		if API_ActorIsOnline(_RoleID) then
			API_OpenWindow(_RoleID,WndID_TaskDialog,0)
			API_ActorSendMsg(_RoleID, 2, "树已枯死")
		end
	end
end


 //--------------------------------------

改良想法:

1, 状态类不应了解其它状态,而应独设一个管理中心由其进行状态间的转换。 管理中心可以监控某状态类的相关信息,例如以触发器的形式监控某状态类。这样对他类的了解工作可以只有管理中心处理,而不用每个相关状态类都要了解,减少了工作。 监控信息则提供了一种在必要时刻对状态进行转换的通用方法。

2, NPC内部可以不用状态类,而是并列几种不同的NPC,例如战斗NPC(主炮),逃跑NPC(轮子)等。 然后“AI塔克”会和这些“主炮”,“轮子”绑定,并在每个适当的时侯由CPU为“AI塔克”提供心跳动力。“AI塔克”可以决定把什么时侯把实体数据套在“主炮”上还是“轮子”上。把内部状态类提到外部实体化,好处是增多状态时,不用去考虑太多该状态的适应环境,更自由随意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值