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塔克”可以决定把什么时侯把实体数据套在“主炮”上还是“轮子”上。把内部状态类提到外部实体化,好处是增多状态时,不用去考虑太多该状态的适应环境,更自由随意。