【1】控件类型是WoWLook/ActionButtonpacket.layout.xml <Window Type="WoWLook/ActionButton" Name="PacketButton_8" > <Property Name="BtnAnimation" Value="" /> <Property Name="Checked" Value="False" /> <Property Name="ClippedByParent" Value="False" /> <Property Name="Default" Value="False" /> <Property Name="DragThreshold" Value="0.000000" /> <Property Name="DraggingEnabled" Value="True" /> <Property Name="Empty" Value="False" /> <Property Name="Gloom" Value="False" /> <Property Name="UnifiedAreaRect" Value="{{0.000000,56.000000},{0.000000,140.000000},{0.000000,90.000000},{0.000000,174.000000}}" /> <Event Name="Clicked" Function="Packet_ItemBtnSubClicked(8);" /> <!--右键单击使用物品的函数 --> <Event Name="RBClicked" Function="Packet_ItemBtnClicked(8);" /> </Window>
【2】WoWLook/ActionButton的右键单击函数packet.luafunction Packet_ItemBtnClicked(nIndex)
if(nIndex < 1 or nIndex > PACKAGE_BUTTONS_NUM) then return; end
-- if( g_bCtrlPressed == 0 )then-- PACKAGE_BUTTONS[nIndex]:DoAction();-- elseif( g_bCtrlPressed == 1 )then-- LifeAbility:Open_Compose_Gem_Page( 0, nIndex - 1 );-- end if ( g_bCtrlPressed == 1 )then LifeAbility:Open_Compose_Gem_Page( 0, nIndex - 1 ); elseif( g_bShiftPressed == 1 )then Open_Rework_Equip( 0, nIndex-1 ); else PACKAGE_BUTTONS[nIndex]:DoAction();--** end
end
<!--这个是UISystem导出的Lua接口函数客户端UI对应的lua脚本只使用两类lua函数,一个是UI控件导出的函数,在UI_CEHUI/UILuaControl.cpp里的,里面有各种控件导出的函数。另一个是Game导出的游戏逻辑函数,在Game/Interface/GMInterface_Lua.h里说明的
【3】DoAction();lua函数Client/UI_CEGUI/UILuaControl.h(177): INT Lua_DoAction(LuaPlus::LuaState* pState); INT ActionButton::Lua_DoAction(LuaPlus::LuaState* pState){ if(m_pActionItem) m_pActionItem->DoAction();// 调用子类的函数,tActionItem* m_pActionItem;
return 0;}
【4】tActionItem是GameInterface里的函数接口tActionItem* m_pActionItem;我们查看所有Game里的继承自tActionItem的类,其实就是Game/Action目录下的类。
可见有很多类型的ActionButton。背包对应的就是GMActionSystem_Item.cpp这个Action模块有个公共的基类class CActionItem : public tActionItem
CActionItem 派生类型 CActionItem_ChangeSuit CActionItem_ChatMood CActionItem_Item CActionItem_LifeAbility CActionItem_MouseCmd_Exchange CActionItem_MouseCmd_Friend CActionItem_MouseCmd_Identify CActionItem_MouseCmd_Repair CActionItem_PetSkill CActionItem_Skill 【5】找到CActionItem_Item的DoAction这里说一下,物品有不同的种类,可以放在不同的背包里,也就是有不同的背包,多种背包, //物品归属 enum ITEM_OWNER { IO_UNKNOWN,
IO_MYSELF_EQUIP, //玩家自己身上的装备 IO_MYSELF_PACKET, //玩家自己身上的包中 IO_MYSELF_BANK, //玩家自己身上的银行中 IO_MYSELF_MOUNT, //玩家自己的坐骑 [7/20/2010] IO_PLAYEROTHER_EQUIP, //其他玩家身上的装备 IO_ITEMBOX, //打开的宝箱中 IO_BOOTH, //商人的货架 IO_MYEXBOX, //自己的交易盒 IO_OTHEREXBOX, //对方的交易盒// IO_ENCHASEPAGE, // 宝石合成/镶嵌界面 IO_MISSIONBOX, //任务递交盒 IO_MYSTALLBOX, //自己的摊位盒 IO_OTSTALLBOX, //对方的摊位盒// IO_APPENDITEM, //装备上附加的宝石 IO_QUESTVIRTUALITEM, // 任务奖励的(虚拟)物品,只用于显示。 IO_PS_SELFBOX, // IO_PS_OTHERBOX, // IO_ITEMDROP, //掉落 IO_ITEMTRANSFER, //用于传送的物品 IO_ITEMIBSHOP, //IBShop
}; ... //玩家自己身上的包中 case tObject_Item::IO_MYSELF_PACKET: { DoAction_Packet(); } break;
... ...GameProjct/trunk/Client/game/Action/GMActionSystem_Item.cppline:4176 普通情况下的使用物品操作:else { //根据装备类型 switch(pItem->GetItemClass()) { case ICLASS_EQUIP: //装备 { //使用★★ CGameProcedure::s_pGameInterface->PacketItem_UserEquip( pItem->GetPosIndex() ); } break; case ICLASS_COMITEM: //药瓶 case ICLASS_TASKITEM: //任务物品类 case ICLASS_STOREMAP: //藏宝图 case ICLASS_SOUL_BEAD: //魂珠 { int iType = pItem->GetItemTableType(); //if ( iType == COMITEM_SOUXIA ) //{ // CEventSystem::GetMe()->PushEvent(GE_OPEN_SOUXIA); // break; //} if ( SCRIPT_SANDBOX::SouXiaLu::s_SouXiaLu.IsSouXiaUsbItem(0,pItem) ) //是 { INT type = SCRIPT_SANDBOX::SouXiaLu::s_SouXiaLu.GetSouXiaUsbType(pItem); if( type != -1 ) CEventSystem::GetMe()->PushEvent( GE_OPEN_SOUXIA, type, 1 ); break; } if ( SCRIPT_SANDBOX::SouXiaLu::s_SouXiaLu.IsSouXiadeformityItem(pItem) ) // { SCRIPT_SANDBOX::SouXiaLu::s_SouXiaLu.ShowSouXiaDeformity(pItem); } //摆摊时不可以随便使用物品 if(TRUE == CObjectManager::GetMe()->GetMySelf()->GetCharacterData()->Get_IsInStall()) { STRING strTemp = ""; strTemp = NOCOLORMSGFUNC("GMActionSystem_Item_Info_You_Stalling"); CEventSystem::GetMe()->PushEvent(GE_NEW_DEBUGMESSAGE, strTemp.c_str()); //CEventSystem::GetMe()->PushEvent(GE_NEW_DEBUGMESSAGE,"你正在摆摊……"); break; } //验证是否可以使用 if(!pItem->Rule(tObject_Item::RULE_USE)) { CEventSystem::GetMe()->PushEvent(GE_NEW_DEBUGMESSAGE, pItem->RuleFailMessage(tObject_Item::RULE_USE).c_str()); break; } //检查冷却是否结束 if(!CoolDownIsOver()) { CActionSystem::GetMe()->SetSetoutAction(this); CGameProcedure::s_pEventSystem->PushEvent( GE_NEW_DEBUGMESSAGE, GetOResultText( OR_COOL_DOWNING ) ); break; } CObject* pMainTarget = (CObject*)CObjectManager::GetMe()->GetMainTarget(); //★★ CGameProcedure::s_pGameInterface->PacketItem_UserItem(this, pMainTarget ? pMainTarget->GetServerID() : -1, fVector2(-1, -1)); } break; case ICLASS_GEM: //宝石 { } break; //坐骑 case ICLASS_MOUNT: { CCharacterData* pCharData = CObjectManager::GetMe()->GetMySelf()->GetCharacterData(); const tDataBase* pdbcbase = CDataBaseSystem::GetMe()->GetDataBase( DBC_ITEM_MOUNT_ATT ); const _DBC_ITEM_MOUNT_ATT* pMountAtt = (const _DBC_ITEM_MOUNT_ATT*)pdbcbase->Search_Index_EQU(pItem->GetIdTable()); if((pCharData != NULL) && (pCharData->Get_Level()< pMountAtt->nNeedLevel)) { // 显示到聊天框 if(bLog) { STRING szMsg = COLORMSGFUNC("Mount_Equip_Fail_For_Grade_Low", pMountAtt->szName);; ADDTALKMSG(szMsg); } return; } //★ CGameProcedure::s_pGameInterface->PacketItem_EquipMount( pItem->GetPosIndex() ); } break; } } 【6】。调用了GMGameInterface.h
cpp:GMGameInterface.cppline:1022的函数
//------------------------------------------------ //使用包裹里的物品_通用 virtual VOID PacketItem_UserItem(tActionItem* pActionItem, int nTargetServerID, fVector2& fvPos) = 0; //使用包裹里的物品_对象 virtual VOID PacketItem_UserItem_ToTarget( INT nIndex, UINT nTargetID) = 0; //使用包裹里的物品_装备 virtual VOID PacketItem_UserEquip( INT nIndex ) = 0; //使用包裹里的物品_宝石 virtual VOID PacketItem_UserGem(INT nGemIndex, INT EquipIndex) = 0; //销毁包裹里的物品 virtual VOID PacketItem_Destroy(INT nIndex) = 0;
CGameProcedure::s_pGameInterface->PacketItem_UserEquip 装备{ ... //进行一系列逻辑验证,最终发送这个包到服务端 CGUseEquip msg; msg.setBagIndex( nIndex ); CNetManager::GetMe()->SendPacket( &msg ); // 服务端返回这个包请求的结果,有可能是多个,伴随着其他属性改变的packet // GCUseItemResult // }返回结果的数据包在Game/Network/Handler/GC.../7.Item/中
CGameProcedure::s_pGameInterface->PacketItem_UserItem 普通物品{ //能够直接使用 CGUseItem msg; msg.SetBagIndex( pItem->GetPosIndex() ); msg.SetTargetObjID(objID); msg.SetTargetPetGUID(petID); msg.SetTargetPos(&posTarget);
CNetManager::GetMe()->SendPacket( &msg ); return; // server返回结果: GCUseEquipResult }CGameProcedure::s_pGameInterface->PacketItem_EquipMount 坐骑{
CGManipulateMount msg; msg.setBagIndex(nIndex); msg.setMountOperator(CGManipulateMount::MANIPULATE_EQUIP_MOUNT); CNetManager::GetMe()->SendPacket( &msg );}