Advertisement
Guest User

Untitled

a guest
Sep 2nd, 2016
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.61 KB | None | 0 0
  1. What this system does:
  2. - Moves units to an arena, allows them to take turns attacking
  3. - Provides a simple way to create custom skills to use in battle
  4. - Provides a simple way to make AI for enemy units
  5.  
  6. What you must do to use it:
  7. - Make your own abilities
  8. - Make your own AI methods
  9. - Link your abilities to your heroes
  10. - Start the battle
  11. - When battle ends perform an action with the result
  12.  
  13. For more details on any part, look at the appropriate readme files.
  14.  
  15.  
  16. This is not as simple as just creating an ability in the object
  17. editor and adding it onto your hero. Every unit is paused, and
  18. remains paused for the entire battle, while a dummy unit lets
  19. you select your abilities. So, we do not want any default skills
  20. here. Instead, create an ability based on "Channel", name it how
  21. you want, and remember the rawcode. For this example, we will use
  22. rawcode 'A000' and name "Attack" - this will teach you how to make
  23. a basic attack function.
  24.  
  25. First, lets register this new skill with the system, to tell it
  26. this is indeed a custom skill. To do this, find the library "Spells"
  27. Find the onInit function. Here is where we register the spell.
  28. Type the following line:
  29.  
  30. call createSpell("Attack","Behavior_attack",'A000',0)
  31.  
  32. This line creates a new ability:
  33. - The name is "Attack"
  34. - The behavior is "Behavior_attack"
  35. - The rawcode is 'A000'
  36. - The mana cost is 0
  37.  
  38. These are all self explanatory, besides the behavior part. The
  39. behavior of a spell is the actual functionality it gets, the code
  40. that runs when someone casts the spell. Since attack is registered,
  41. lets go make the behavior. Find the "Behaviors" library in the
  42. system, and scroll to the comment //-- User made behaviors --//
  43.  
  44. First, we name our behavior the same as we specified before:
  45.  
  46. public function attack takes nothing returns nothing
  47. endfunction
  48.  
  49. Now, when a unit attacks, this function will run. But it takes
  50. nothing, so how do we know who the attacker is? Well, we have
  51. an Action reference that saves those. So, inside the body, type
  52. the following:
  53.  
  54. local Action act = Spells_spellCast
  55. local unit src = act.getSource()
  56. local unit target = act.getTarget()
  57. local Battle whichBattle = act.getBattle()
  58.  
  59. Spells_spellCast saves the last used Action. We can then use this
  60. action to get the source, target, and battle that its in, as seen
  61. above. The next thing: the action selector can still give orders
  62. right now, but we do not want that.. or else the user could just
  63. order a bunch of times, and attack more than once. So, call
  64. the following:
  65.  
  66. call whichBattle.pause()
  67.  
  68. Now we need to code the actual attack. This is different
  69. for each map, and its up to you how you want to code it. In general
  70. though, the attack would play the attack animation and deal some
  71. damage. After this though, we are not done! If we leave the
  72. function off after dealing damage, the battle will never continue
  73. because we paused it! Instead, we call the following:
  74.  
  75. call whichBattle.next()
  76.  
  77. If you want the same unit to be able to take another action, you
  78. could call the following:
  79.  
  80. call whichBattle.resume()
  81.  
  82. Note: item abilities work exactly the same as normal abilities.
  83. So give your heroes any items you want, just code the skills!
  84.  
  85. Note: If the Behaviors library gets cluttered, extract each spell
  86. code to a new library, and have Behaviors call it!
  87.  
  88. //--------------------------------------------------------------//
  89.  
  90. Short version/recap:
  91.  
  92. 1) In Spells library, add the following to onInit:
  93. call createSpell("myName","Behavior_myFunction",'RAW',manaCost)
  94. 2) In Behavior library, add the following function:
  95. public function myFunction takes nothing returns nothing
  96. local Action act = Spells_spellCast
  97. local unit src = act.getSource()
  98. local unit target = act.getTarget()
  99. local Battle whichBattle = act.getBattle()
  100. call whichBattle.pause()
  101. //Code for this ability goes here!
  102. call whichBattle.next()
  103. endfunction
  104.  
  105.  
  106. Coding AI is much harder than coding abilities, but as far as the
  107. system goes, its registered much the same. Find the "AI List" library
  108. and go to the onInit function, and register the AI. For this example,
  109. I will use a footman for the unit I want to make AI for:
  110.  
  111. call createAI('hfoo',"Behavior_Footman_AI")
  112.  
  113. Now we registered 'hfoo' (footman) to Behavior_Footman_AI. Now
  114. we need to go code it in the behaviors section. Find "Behaviors"
  115. and go to the comment //-- User AIs --//
  116. Add the following code:
  117.  
  118. public function Footman_AI takes nothing returns nothing
  119. endfunction
  120.  
  121. Now, whenever its a footmans turn in battle, this function will
  122. immediately be called. In the same way as spells, we have a
  123. reference to the AI that we can grab to find out which battle hes
  124. in, and who the unit is to begin with:
  125.  
  126. local AI ai = AIList_whichAI
  127. local unit aiUnit = ai.getAIUnit()
  128. local Battle battle = ai.getBattle()
  129. local unit target = null
  130. local Action whichAction = 0
  131.  
  132. ai is the reference to the AI object corresponding to this unit.
  133. aiUnit is the ai unit whose turn it is
  134. battle is the battle the ai is in.
  135. target and whichAction are not set. We will use those later.
  136.  
  137. Now its time to actually code the AI. Youll need to add whatever
  138. logic you want in (maybe an hp check, for example), and then force
  139. the unit to take an appropriate action. We will do this by using
  140. the whichAction object. Set it like this:
  141.  
  142. set whichAction = Spells_convertAbilityNameToAction("Attack")
  143.  
  144. This will return the action with the name specified. In this
  145. example, I get the Attack action - this obviously has to be created
  146. and registered previous to using. Now, we need our target. You may
  147. want to include some logic here to find a target too, but for this
  148. we will just select a random hero:
  149.  
  150. loop
  151. exitwhen target != null and IsUnitAliveBJ(target)
  152. set target = GroupPickRandomUnit(battle.heroes)
  153. endloop
  154.  
  155. This part will make sure that we select a living unit. We dont
  156. want to try to attack a dead unit, so we loop until we find
  157. a living one. Now all thats left to do is run the action!
  158.  
  159. call whichAction.run(aiUnit,target,battle)
  160.  
  161. And thats it. We dont need to advance the battle here, since the
  162. action does it for us.
  163.  
  164. //------------------------------------------------------------//
  165.  
  166. Short version/recap:
  167.  
  168. 1) In AI List library, register the new AI type
  169. - call createAI('UNITTYPE',"Behavior_My_AI")
  170. 2) In Behavior, code the AI function like this
  171. public function My_AI takes nothing returns nothing
  172. local AI ai = AIList_whichAI
  173. local unit aiUnit = ai.getAIUnit()
  174. local Battle battle = ai.getBattle()
  175. local unit target = null
  176. local Action whichAction = 0
  177. //Your AI logic here
  178. set whichAction = Spells_convertAbilityNameToAction("Action to take")
  179. call whichAction.run(aiUnit,target,battle)
  180. endfunction
  181.  
  182. This is by far the easiest part. We need two unit groups, one for
  183. heroes, one for enemies. We need a point (center of battle) to
  184. create it at, and we need to know the size of the arena to use.
  185.  
  186. So first, we create a new battle:
  187.  
  188. local Battle b = Battle.create()
  189.  
  190. Now we set where the battle will take place:
  191.  
  192. call b.setX(myX)
  193. call b.setY(myY)
  194.  
  195. Here, we pass in the groups of heroes and enemies. Note that these
  196. groups will not be destroyed by the system, so you must destroy them
  197. (or reuse them, if thats what makes sense for your map)
  198.  
  199. call b.setEnemies(udg_TempGroup1)
  200. call b.setHeroes(udg_TempGroup2)
  201.  
  202. Now the size. If you have trouble finding this, create a region
  203. over the arena and measure ((x2 - x1), (y2 - y1)). For here, Ill
  204. assume an area of 1000 x 1000
  205.  
  206. call b.setArenaSize(1000,1000)
  207.  
  208. All thats left is starting the battle.
  209.  
  210. call b.start()
  211.  
  212. //---------------------------------------------------------------//
  213.  
  214. Short version/recap:
  215.  
  216. local Battle b = Battle.create()
  217. call b.setX(myX)
  218. call b.setY(myY)
  219. call b.setEnemies(udg_TempGroup1)
  220. call b.setHeroes(udg_TempGroup2)
  221. call b.setArenaSize(1000,1000)
  222. call b.start()
  223.  
  224. Since ability use it entirely triggered with a dummy, you need to
  225. save which heroes can use which abilities. Simply adding them to
  226. the hero will do nothing in battle. There is a structure to do this:
  227. the SkillsList. AI does not need a skills list, but the heroes in
  228. the battle need one - there should be only one SkillList for the
  229. whole heroes group.
  230.  
  231. First, initiate a skills list.
  232.  
  233. local SkillsList skills = SkillsList.create()
  234.  
  235. Now, for the FIRST hero in the group of heroes, add your skills.
  236.  
  237. call skills.add('A000')
  238. call skills.add('A001')
  239.  
  240. Now if there is another hero, tell the system that youre entering
  241. a new one by using the next function.
  242.  
  243. call skills.next()
  244.  
  245. Now add abilities for the second hero.
  246.  
  247. call skills.add('A002')
  248. call skills.add('A003')
  249.  
  250. Finally, when all heroes have been added, call next one more time.
  251.  
  252. call skills.next()
  253.  
  254. All thats left to do is pass this to the battle youve created.
  255.  
  256. call b.setSkills(skills)
  257.  
  258. And youre done! In addition, there are several convience functions
  259. in the SkillsList structure. These can:
  260. 1) Add a skill to a previously added hero
  261. 2) Remove a skill (by id)
  262. 3) Remove a skill (by location) (make sure to select the correct one)
  263.  
  264. call skills.insert(heroNum,abilityId)
  265. call skills.remove(abilityId)
  266. call skills.removeAt(index)
  267. //BEWARE: each "next" creates an entry too. You can
  268. //remove the "nexts", but should be done with caution
  269.  
  270. //--------------------------------------------------------------//
  271.  
  272. Short version/recap:
  273.  
  274. local SkillsList skills = SkillsList.create()
  275. call skills.add('A000')
  276. call skills.add('A001')
  277. call skills.next()
  278. call skills.add('A002')
  279. call skills.add('A003')
  280. call skills.next()
  281. call b.setSkills(skills)
  282.  
  283. Since every map is different, we need code to do something when
  284. the battle ends. This might be giving gold/exp to the player, or
  285. game-overing the player depending on the result. So first, detecting
  286. when its over. We have several functions to help with this.
  287. Assuming we have Battle b running:
  288.  
  289. b.isBattleOver() //determines whether it is over at all
  290. b.hasPlayerWon() //determines if player won
  291. //so if battle is over, and player hasn't won, then AI won
  292.  
  293. There are many different ways of detecting this; you can decide on
  294. your own, or use my way:
  295.  
  296. loop
  297. exitwhen b.isBattleOver()
  298. call PolledWait(1.0)
  299. endloop
  300.  
  301. Simple enough. Some might object to it because it has a wait, but
  302. this code is for your map, not the system, so its completely your
  303. choice. Now, determine the result.
  304.  
  305. if(b.hasPlayerWon())then
  306. //give gold/xp
  307. else
  308. //game over
  309. endif
  310.  
  311. Move all units back to their original locations. How you want to
  312. do this depends entirely on your map. The last action to do is
  313. to destroy the battle to free up memory.
  314.  
  315. call b.destroy()
  316.  
  317. //--------------------------------------------------------------//
  318.  
  319. Short version/recap:
  320.  
  321. loop
  322. exitwhen b.isBattleOver()
  323. call PolledWait(1.0)
  324. endloop
  325. if(b.hasPlayerWon())then
  326. //give gold/xp
  327. else
  328. //game over
  329. endif
  330. //move heroes to original locations
  331. call b.destroy()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement