Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   Scripts (http://www.wc3c.net/forumdisplay.php?f=737)
-   -   LastOrder (http://www.wc3c.net/showthread.php?t=104175)

Rising_Dusk 01-19-2009 08:39 AM

LastOrder
 
1 Attachment(s)
LastOrder Library

Background:
This library of code allows lots of cool interfacing with the last orders of a unit. The main point of the library is to maintain an organized list of up to N of any given unit's last issued orders. The value of this is that you can recall those orders at any time and reissue them if the need arises. (Such as if those orders were lost to the unit by a pause/stop/pause or something similar) Thanks to ToukoAozaki for giving me the motivation to package and release it.

Requirements:
  • None
Code:
Expand Library:

Function List:
This library gives the following interfacing options with last orders. It contains the following functions for use with interfacing last orders given to a unit.
  • function GetPastOrder takes unit u, integer whichOrder returns order
  • function GetPastOrderId takes unit u, integer whichOrder returns integer
  • function GetPastOrderString takes unit u, integer whichOrder returns string
  • function GetPastOrderType takes unit u, integer whichOrder returns integer
  • function GetPastOrderX takes unit u, integer whichOrder returns real
  • function GetPastOrderY takes unit u, integer whichOrder returns real
  • function GetPastOrderTarget takes unit u, integer whichOrder returns widget
  • ----
  • function GetLastOrder takes unit u returns order
  • function GetLastOrderId takes unit u returns integer
  • function GetLastOrderString takes unit u returns string
  • function GetLastOrderType takes unit u returns integer
  • function GetLastOrderX takes unit u returns real
  • function GetLastOrderY takes unit u returns real
  • function GetLastOrderTarget takes unit u returns widget
  • function IsLastOrderFinished takes unit u returns boolean
  • ----
  • function IssuePastOrder takes unit u, integer whichOrder returns boolean
  • function IssueLastOrder takes unit u returns boolean
  • function IssueSecondLastOrder takes unit u returns boolean
  • function IssueArbitraryOrder takes unit u, order o returns boolean
  • function AbortOrder takes unit u returns boolean
In the documentation, I explain a lot about why a user wants to store the last 3 orders a unit has received. The second and third orders are particularly useful for use with spells that target either units or locations and need to be intercepted. These spells are 'interrupted' on the SPELL_CAST event to prevent cooldown/mana cost, but that fires after the order events. This means that in the case where you want to reissue the order before you cast storm bolt, you need to now issue your second to last order. If you issue the very last order, you run into spell recursion, which is a whole bunch of nastiness that no one wants to look at.

Attached to this post is a demo map showing you how the system works. You can hit escape to view the last order details for your blademaster at any given time. Additionally, you can issue orders around the map and then use the "Demo Spell" with the cancel icon. That spell does nothing, but it is intercepted by an example code in the demo map and takes advantage of the following AbortSpell library, which was designed to be used with the LastOrder library. This should be a sufficient example for anyone to figure out how to use it in their maps to its fullest extent.

_______________________________________________________________________

AbortSpell Supplementary Library

Requirements:
Expand Supplementary Library:

Function List:
This library gives the following function to the user.
  • function AbortSpell takes unit u, string msg, string key returns boolean
This expands upon SimError to fully simulate WC3 spellcasting errors. When you try to cast a spell in WC3 and you can't, you keep following your last order and the AOE indicator and so forth don't go away. If you used only the normal SimError, you couldn't fully simulate this special case, but with AbortSpell you can. AbortSpell also takes a 'key' argument, which corresponds to the hotkey associated with your spell.

Thanks guys, comments are welcome!

C2H3NaO2 01-19-2009 11:17 AM

1 Attachment(s)
That a really greet idea!

But on my pc (wc3 1.21b) it tells me about hit op limit in the init function.
For me it works without the initialization loop exactly the same like before.

+Rep

Iron_Doors 01-19-2009 02:06 PM

I found two problems using the cancel spell in your test map. First was that if you cast Mirror Image and then do nothing until its cooldown wears off and then use the cancel spell, the hero recasts Mirror Image. Second was that shift orders are forgotten when the error spell is used.

Also, I would name those ORDER_TYPE_ constants according to the Issue(Target|Point|Immediate)Order functions that they are associated with.

Vexorian 01-19-2009 02:17 PM

I think SimErrorEx should be separated in another module, mostly because I think that the current method is not the best possible, but the alternative requires more code, pausing units is a little problematic, often I prefer to give the correct order after a 0.0 seconds timer rather than pause the unit.

edit: Making SimErrorEx a separate thing will also allow the main library to get rid of the SimError requirement.

Here-b-Trollz 01-19-2009 02:29 PM

Fuck yes. You rule Dusk. I've been meaning to do something like this for a long time, and now I don't have to. Pro.

Rising_Dusk 01-19-2009 05:38 PM

Quote:

Originally Posted by Iron_Doors
I found two problems using the cancel spell in your test map. First was that if you cast Mirror Image and then do nothing until its cooldown wears off and then use the cancel spell, the hero recasts Mirror Image. Second was that shift orders are forgotten when the error spell is used.

Ah yes, shift orders. Queued orders are forgotten no matter what, it's an inevitability. Also, the Mirror Image recast just means I forgot a check in the LastOrderFilter function. I guess I should have it disallow INSTANT orders as well.

EDIT:
Actually, thanks for the report. It seems I was checking Order and not P_Order, the second to last order. Fixing that bug now.
Quote:

Originally Posted by Vexorian
I think SimErrorEx should be separated in another module, mostly because I think that the current method is not the best possible, but the alternative requires more code, pausing units is a little problematic, often I prefer to give the correct order after a 0.0 seconds timer rather than pause the unit.

edit: Making SimErrorEx a separate thing will also allow the main library to get rid of the SimError requirement.

Okay, I will make it a separate module, then. But your note about the pausing not being the best way troubles me. I thought pause/stop/unpause was the only known way to fully stop a unit from losing mana/etc. on casting a spell? If there's a better way that doesn't involve the use of pause, lay it on me and I'll use it. I've just always used it because I know it works.

Let me split the library up a bit, I'll update shortly.
Quote:

Originally Posted by Here-b-Trollz
Fuck yes. You rule Dusk. I've been meaning to do something like this for a long time, and now I don't have to. Pro.

<3

Anitarf 01-19-2009 06:42 PM

Is it really required to initialize all those array values? Aren't uninitialized arrays effectively the same as initial values of 0/null as far as comparisons go?

While not a requirement, it is my suggestion that you make an additional "flavour" of this library using table; in any case this can wait until the end of the review process when the indexing version of the library will be finalised.

Vexorian 01-19-2009 07:27 PM

This is the sort of thing in which I wouldn't use Table, It would at least need a unit group trick to be safe.

Rising_Dusk 01-19-2009 08:47 PM

Okay, I split them up and fixed all of the documentation. I also removed those array initializations, since Ani cleared up that one for me.

Vexorian 01-21-2009 03:17 PM

I think it is a good thing. Though I suggest you to make a UnitIndexingutilities that doesn't use user data so that people are not disallowed to use it if user data is used by something else. hmnn.

Rising_Dusk 01-21-2009 03:34 PM

Quote:

Originally Posted by Vexorian
Though I suggest you to make a UnitIndexingutilities that doesn't use user data so that people are not disallowed to use it if user data is used by something else. hmnn.

Okay, I'll look into making a flavor of UnitIndexingUtils that doesn't require UserData sometime. I really think that UserData should be reserved for unit indexing anyways, since once you index the unit you have a port with which to associate infinite data to that unit.

Vexorian 01-21-2009 03:50 PM

It kind of becomes an issue when there are thousands of different indexing systems.

Rising_Dusk 01-21-2009 04:11 PM

That's certainly true. I wish we could streamline the use of userdata (like with UnitIndexingUtils) like you did timers (with TimerUtils) and gamecache (with Table); it would remove the fuzziness in that sort of thing.

Av3n 02-11-2009 09:19 AM

Just to remind you from my PM.

Is it possible that you can create a "flavor" which uses Table instead of your own system Unit Indexing Utilities.

I reckon Table has a higher (I don't think it is the right term oh well) re-use-ability rate. So I highly suggest that you do.

-Av3n

Rising_Dusk 02-11-2009 12:50 PM

I thought about this. The problem with having two versions requiring different libraries is that then it becomes absolutely critical which version of the library users are using. It may as well be like having two entirely different libraries, since they are not interchangeable with each other at all.

I'll ask Vex/Ani about it and then go from there, more than likely.


All times are GMT. The time now is 04:23 AM.

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services