LUA実装状態モード

12905 ワード

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.ステータスクラスは、他のステータスを理解するのではなく、管理センターを1つだけ設けてステータス間の変換を行う必要があります.管理センターは、ステータスクラスに関する情報を監視できます.たとえば、トリガとしてステータスクラスを監視できます.このように、彼のクラスの理解作業は管理センターだけで処理することができ、関連するステータスクラスごとに理解する必要がなく、仕事を減らすことができます.モニタリング情報は、必要に応じて状態を変換する一般的な方法を提供する.
2,NPC内部は状態類ではなく,戦闘NPC(主砲),逃走NPC(車輪)など,いくつかの異なるNPCを並べてもよい.その後、「AIタック」はこれらの「主砲」、「車輪」とバインドされ、各適切なタイミングでCPUによって「AIタック」に心拍動力を提供する.「AIタック」は、いつ実体データを「主砲」にかぶせるか、「車輪」にかぶせるかを決めることができる.内部状態クラスを外部実体化に言及すると,状態を増やした場合,その状態の適応環境をあまり考慮せず,より自由で自由であることが利点である.