拉比克偷取他人技能,在代碼程序層面時如何實現的?

如題


Dota2的原理不太了解了,我說說Dota1時代是如何實現這個效果的。

(準確的說是War3製作技能的一般常見實現方法,dota 沒見過代碼,但應該也是)

----------------------------------------- 長篇 廢話 ----------------------------

首先war3時期,受war3本身制約,war3本身不支持製作技能,只有默認的那些,那些技能很難完成各種各樣華麗的效果。不過雖然技能不能直接改,但製作者卻可以控制各種單位進行任何活動。

於是就有人了想到了 我可以在讓一個人物 在使用閃爍後自動放一個戰爭踐踏,只要夠快那玩家自然會覺得這是一個技能,然後再加個絢麗的動畫,這不就好了。

但是這樣這個人物的技能太多了,載入人物就要載入一堆技能,太慢了,人如果多怎麼辦?(所以dota1選卡爾會卡一下)

然後就出現了 第二種方案,你放技能時,你本人只管擺pose,然後在你身邊創造一個 歸屬於你的單位由他代為放技能,放完了技能立馬自殺,做的好的作者,這個創造出來的模型是透明的(不是隱身,是不論怎樣都不可見),做的渣的...不忍直視啊

(所以有些渣地圖裡,你放冰火兩重天時,你旁邊會出現一個大法師和個深淵魔王,所以war3的真三國無雙里 司馬懿開大可以造房子...)

所以後來的通用方案都是 用不可見人物代替角色放技能 好了該聊到正題了。

-------------------------------------------- 個人想法 ---------------------------------------------

如上,war3里的技能基本上由 不可見的單位代為釋放的,一般稱為「馬甲」,而一般技能都有一個對應的方法,這個方法裡面調用一個或則多個馬甲。

首先,多給拉比克一個變數,同時添加一個定時器,讓定時器每隔120+10*lv(大招等級) 清空一次變數,之後在拉比克放技能後只需要尋找對方技能對應的方法,存到這個變數裡面,然後調用即可。

//看到別人列代碼,我也想秀一下。然而大專三年下來發現基本上啥代碼也沒學會多少(? _ ?)
//用java 寫了一個思路,我發現連java都快不會寫了,諸君再見,我回爐重造了o(︶︿︶)o 。
private Date timer = new Date();
private int level = 0;
private Method fun;
void clear(){
Date now = new Date();
if(level == 0 || now.getTime() - timer.getTime() &>= 60 + 60 * level)
fun = null;
}
void fun4(int hreoId){
fun = Hreo.getLastFunById(hreoId);
}
void fun5(int hreoId){
if(fun != null)
fun.invoke(hreoId);
}

----------------------------------------- 回復 @太原黑土巷馬建國 --------------------------------------

dota1時期基於war3,而war3不允許自定義技能,但觸發事件(比如 攻擊時如何如何,走到一個區域時如何如何這種)是可以隨意編寫的。

就是說 像小Y的束縛 你可以直接用,但像蝙蝠騎士的你卻不能直接寫,沒有編輯技能這個選項。最後的妥協方案是蝙蝠開大時在他身邊創建一個隱身無碰撞的JJ,然後由他釋放枷鎖,當你移動時強行將這個隱身的j和敵人一起偏移相應的坐標。


技能本身是個對象。拉比克這個英雄對象直接有一個技能屬性。吧對方的技能賦值給拉比克就完事了啊。。。


小時候做過war3地圖開發

war3地圖採用暴雪自己設計的jass腳步語言

這個語言不是OOP語言 沒有對象 沒有實例 沒有繼承 沒有多態 甚至不能定義自定義類型 不能動態分配自定義類型內存(因為本來就沒有自定義類型)

所以war3每個腳本編寫的技能確實是一個函數

這裡要解決一個最關鍵的問題 我們怎麼建立一個對象 讓他有獨立的屬性 因為只有內置類型可以動態分配 並且調用create函數後返回一個關聯到對象實例的句柄 因為我們無法創建自定義類型 所以我們只能換個思路 能不能把一系列數據綁定到已有的實例上 那麼對於每個實例就等於有一套附加屬性了(和wpf的附加屬性幾乎一樣的概念)

其實實現很簡單 就是用內部類型的實例句柄作為映射結構的key 用這個key去索引和修改value

這樣一來我們就能利用內置類型擴展出一個擁有很多附加屬性的對象了

比如我們可以在一個單位身上附加一個幸運屬性

所以克拉比的盜取很簡單 直接把技能設置給他就行了 不同的施法者都有自己的一套綁定在施法者單位自身句柄的附加屬性用於實現技能 所以不同單位不會衝突


其實想一想,在DotA1的時候,蠟筆可偷很多技能是有BUG的,而且包括很多人說的雙偷也是有BUG,而DotA2修復了這些BUG,我認為是在結構設計上有所改良。

個人假想:

DotA1:以函數驅動,換句話說技能是函數,偷來的技能以改參數驅動,所以才會在執行的時候由於技能固有的問題,無法在參數改變的時候正確執行

DotA2:以對象驅動,所以技能是可以存在繼承關係的,這樣維護起來十分方便,所以像是蠟筆可偷蝙蝠火或者劍聖轉這種技能動畫也改變是很容易的


技能列表相應的位置賦值成相應的元素不就好了


玩過OMG的應該都知道,dota1裡面的英雄技能是可以相互組合的,所以技能應該是一個對象而不是函數,正常模式下每個英雄都是用默認技能表初始化英雄,OMG模式下可以隨意組合技能,應該更加鬆散的聚合而非繼承


委託。


rubick = new hero();

rubick.setSkills(getSkills("rubick"));

rubick.getSkills()[5] = rubick.useSkill(4);

rubick.useSkill(5);

好吧 我瞎比寫的。 這個要寫詳細點。。


技能本身是一段腳本。釋放技能就是以自己和目標作為參數執行腳本。蠟筆克偷到技能釋放,只要執行對應技能的腳本即可。


拉比克是個對象 而技能是對象的一個屬性或方法

所以寫一個複製屬性或方法的代碼就可以了另外:Dota2的技能實現是用Lua寫的,Valve魔改了Source Engine在底層上加入了超級多的API供Lua來調用寫技能。但是原始技能直接集成到了引擎中,無法直接修改。


skill就是一個class,set get很簡單


樓主玩過OMG沒


rubick = new Hero()

....

rubick.setSkill( 4, otherHero.getRecentSkill() )


ASM


其實這個問題很簡單,魔獸爭霸3自帶的編輯器有一套專門的代碼。dota2就不知道了。


我並不懂什麼代碼但是我的思路肯定是每個技能都有一個ID

只要獲取該技能ID然後讀取就能達到偷取技能的效果了吧。。


推薦閱讀:

有哪些適合編寫 C / C++ 的軟體?
如何求解傅里葉17線難題?
Win10 總有一個好像命令行窗口的彈窗一閃而過,怎麼找到到底是什麼問題?

TAG:代碼 | 程序 | 刀塔DOTA2 | 遊戲編程 |