World of Warcraftへのアドオンの書き込み

どういうわけか、彼らはWoWのボットの作成についてhabrに書いたが、アドオンを書くことに関する記事を見つけられず、このプロセスを、かつて私がまだ学生で、プレイするのに十分な時間に一度書いた1つの手芸の例として説明することにしたWorld of Warcraftとそれにアドオンを作成します。 当時はお金がかからなかったので、公式サーバーではなく、無料サーバーの1つでプレイしました。無料サーバーには、不完全さ、バグ、機能、異常がたくさんあります。





そのうちの1つを誤って使用することを禁止された後、公式シャードとのこのシャードの違いをすべてゲーム内で示し、使用に対するペナルティーについて警告するアドオンを作成するというアイデアが生まれました。



Google Codeとサーバーのフォーラムにアドオンを投稿し、非常に人気がありました(海賊版サーバーに関して)。 アドオンの作成方法を誰が気にするか-猫の下のWellcomesに。



はじめに



それでは、定義から始めましょう。 WoWのアドオンは、ユーザーがゲームのクライアント部分のインターフェイスを変更できるようにするが、サーバーゲームの仕組みには影響しない、いくつかのファイルのセットです。 当初はアドオンがWoWであったため、このMMORPGは他のアドオンと区別され、その優位性について叫びましたが、今日まで公式のアドオンを作成することはできません。 アドオンは数万ではありませんが、数万あります。 なぜそんなに多いのですか? しかし、ゲームスタイルとゲームタスクの数はまったく同じだからです。 そしてもちろん、開発者は素晴らしいです。最初から、誰もが単一のインターフェースを課すのではなく、自分自身で何かを作成する方法を提供し、便利であると考える必要がありました。



アドオンを作成するためのドキュメントのメインソースはWoWWikiポータルです。 いくつかの関連リンク:



有用な情報はまだたくさんありますが、2、3回クリックするだけで、これらの4つのページからのリンクからアクセスできます。



ツールキット



アドオンを作成するための特別なツールは必要ありません。 これらはすべてテキストファイルなので、お気に入りのテキストエディタを入手してください。 Lua言語の構文強調表示がある場合(アドオンが作成されます)-通常は問題ありません。 たとえば、Notepad ++はこれらの要件を満たしています。

また、愛好家は、 Free Visual Studio Shellエンジンに基づいて、 AddOn Studioと呼ばれる特別なオープンソースIDEを作成しました。







クールなもので、次のような多くの機能を引き受けます。



+その他のクールなもの。 一般に、使用できます。 まあ、あなたはこのページを閲覧することもできます 。多分あなたはあなたのお気に入りのIDEのためのプラグインまたはちょうど身近なものを見つけることができます。



概念的な瞬間







アドオンの構成



1. TOCファイル (コンテセットのテーブル)。 これは、アドオンの目次です。 WoWシェルに、私たちが誰であるか、何と呼ばれているのか、誰が著者であるのか、何から構成されているのか、その他いくつかのことを説明します。 たとえば、ここに私のアドオンのtocファイルがあります:

## Interface: 30000 ## Title: Wnet Featurer 1.3 ## Notes: Wnet Server Features List ## RequiredDeps: ## OptionalDeps: ## LoadWith: Blizzard_TalentUI ## SavedVariables: Data.lua WnetWarnings.lua WnetFeaturer.xml
      
      







2.作成するインターフェイスの変更を記述したXMLファイル (フレーム、ボタン、インターフェイスのイベントをコードの特定の機能にバインド)。 これが私のアドオンのxmlファイルです。

 <Ui xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.blizzard.com/wow/ui/" xmlns="http://www.blizzard.com/wow/ui/"> <Script file="WnetFeaturer.lua" /> <Frame name="WnetFeaturerFrame"> <Scripts> <OnLoad> WnetFeaturer_OnLoad(self); </OnLoad> <OnEvent> WnetFeaturer_OnEvent(self, event, ...); </OnEvent> </Scripts> </Frame> <Frame name="GameTooltip" parent="GameTooltip"> <Scripts> <OnUpdate> WnetChecker_GameTooltip_OnUpdate(); </OnUpdate> </Scripts> </Frame> </Ui>
      
      







ここに何が書かれていますか? このインターフェイスファイルのWnetFeaturer.luaコードファイルへのバインドを宣言し、2つのフレームを宣言します-1つはプラグインの読み込みイベントでイベントをハングアップするためのもので、2つ目はゲーム内で使用され、ゲームワールドの特定のオブジェクトに独自のツールヒント(ヒント)を表示します。



3. Luaファイル 。 これはLuaコードです。 確かに、WoWのLuaは多少削除されています(詳細はWoWWikiで確認できます)が、ほとんどのタスクにはこれで十分です。 これがアドオンコードファイルの1つです(最短)。



 --     (    ) local before_wnet_featurer_old_QuestFrameDetailPanel_OnShow = QuestFrameDetailPanel_OnShow; function WnetFeaturer_Log( text ) SELECTED_CHAT_FRAME:AddMessage( text ); end function WnetFeaturer_OnLoad(self) if ( not IsAddOnLoaded( "Blizzard_TalentUI" ) ) then _, reason = LoadAddOn( "Blizzard_TalentUI" ); end if ( reason ) then return; end -- Hook the Talent Frame's Update function hooksecurefunc( "TalentFrame_Update", Planner_TalentFrame_AfterUpdate ); -- Register for Loading Variables self:RegisterEvent( "PLAYER_ENTERING_WORLD" ); self:RegisterEvent( "PLAYER_LEAVING_WORLD" ); -- Locale/Gender-neutral class names FTW wnet_featurer_classes = { [1] = "DEATHKNIGHT", [2] = "DRUID", [3] = "HUNTER", [4] = "MAGE", [5] = "PALADIN", [6] = "PRIEST", [7] = "ROGUE", [8] = "SHAMAN", [9] = "WARLOCK", [10] = "WARRIOR", }; end function WnetFeaturer_OnEvent( self, event, ... ) if ( event == "PLAYER_ENTERING_WORLD" ) then tp_name = UnitName( "player" ).." of "..GetRealmName(); _, class = UnitClass( "player" ); for k, v in ipairs( wnet_featurer_classes ) do if ( v == class ) then tp_class = k; end end elseif ( tp_name ) then if ( event == "PLAYER_LEAVING_WORLD" ) then tp_name = nil; tp_class = nil; end end end function Planner_TalentFrame_AfterUpdate( frame ) local page = PanelTemplates_GetSelectedTab( PlayerTalentFrame ); local numTalents = GetNumTalents( page ); local inspect = PlayerTalentFrame.inspect; local pet = PlayerTalentFrame.pet; local _, class = UnitClass( "player" ); if ( pet or tp_standby or not tp_name or not tp_class or frame ~= PlayerTalentFrame or inspect ) then return; end for id = 1, numTalents, 1 do local name, texture, row, col, rank, maxRank = GetTalentInfo( page, id ); local color = nil; if( wnet_talents[tp_class][page][name] ) then color = wnet_talents[tp_class][page][name]; else color = NORMAL_COLOR; end if ( color ) then getglobal( "PlayerTalentFrameTalent"..id.."Slot" ):SetVertexColor( color.r, color.g, color.b ); getglobal( "PlayerTalentFrameTalent"..id.."RankBorder" ):Show(); getglobal( "PlayerTalentFrameTalent"..id.."Rank" ):SetText( rank.."/"..maxRank.." " ); getglobal( "PlayerTalentFrameTalent"..id.."Rank" ):Show(); else getglobal( "PlayerTalentFrameTalent"..id.."RankBorder" ):Hide(); getglobal( "PlayerTalentFrameTalent"..id.."Rank" ):Hide(); end end end function checkIsItemValid( text ) if ( wnet_items[text] ) then return 1; else return nil; end end function checkIsNPCValid( text ) if ( wnet_npc[text] ) then return 1; else return nil; end end WnetChecker_GameTooltip_OnUpdate=function() local errorString = nil; for i=1, GameTooltip:NumLines(), 1 do local currentTooltipStr = getglobal("GameTooltipTextLeft"..i):GetText(); --   NPC   if ( i == 1 ) then -- NPC        .    . if( checkIsNPCValid( currentTooltipStr ) ) then errorString = "Wnet:  NPC   !"; elseif( checkIsItemValid( currentTooltipStr ) ) then errorString = "Wnet:     !"; end end if strfind( currentTooltipStr, "Unique(.)Equipped" ) then errorString = "Wnet:  2   !"; elseif strfind( currentTooltipStr, "Target Dummy" ) then errorString = "Wnet:  2   !"; elseif( strfind( currentTooltipStr, "Chance on hit(.) Stuns target for" ) or strfind( currentTooltipStr, "Chance on hit(.)   " ) ) then errorString = "Wnet:    !"; elseif( strfind( currentTooltipStr, "Chance on hit(.) Knocks target silly for" ) ) then errorString = "Wnet:    !"; elseif( strfind( currentTooltipStr, "Blackblade of Shahram" ) ) then errorString = "Wnet:    !"; elseif( strfind( currentTooltipStr, "Seduction" ) ) then errorString = "Wnet:   !"; elseif( strfind( currentTooltipStr, "Ursius" ) or strfind( currentTooltipStr, "Avian Darkhawk" ) or strfind( currentTooltipStr, "Avian Ripper" ) or strfind( currentTooltipStr, "Windroc Matriarch" ) ) then errorString = "Wnet:   !"; elseif( strfind( currentTooltipStr, "Wnet:") ) then errorString = nil; end end if errorString then GameTooltip:AddLine( errorString, 1, 0, 0 ); local i; local s=10; for i=1, GameTooltip:NumLines(), 1 do s=s+getglobal("GameTooltipTextLeft"..i):GetHeight()+2; end GameTooltip:SetHeight(s+10); GameTooltip:SetWidth( max( GameTooltip:GetWidth(), 300 ) ); end end function checkIsQuestNotValid( questTitle ) if ( wnet_quests[questTitle] ) then return 1; else return nil; end end QuestFrameDetailPanel_OnShow=function() before_wnet_featurer_old_QuestFrameDetailPanel_OnShow(); if( checkIsQuestNotValid( GetTitleText() ) ) then QuestDescription:SetText("|c00ff0000 Wnet:     !|r|n"..GetQuestText()); end end
      
      





このコードは次のタスクを実行します。





プロジェクトにはいくつかのコードファイルがありますが、大部分は無効なオブジェクトとそれらへの署名のベースにすぎません。 関心は生じません。

完全なソースはここで見つけることができます: http//code.google.com/p/wnet-featurer/downloads/list

そして、ここにフォーラムのトピックがあり、そこでアドオンの機能をより詳細に説明しました。



これが誰かを助けてくれたら嬉しいです。 不明な点があるかどうか尋ねます。



All Articles