HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

AWall - Wall Detection System

07-16-2008, 01:40 AM#1
Strilanc
Summary
A very common problem for tower defense games is detecting when a player is taking advantage of unit pathing. The typical solution involves hoping units attack if they are walled and is very easy to defeat. AWall detects when units have been walled.

The system currently uses HAIL and SUEL [included in the example map], and requires vJass. The example map includes a GUI extension for people who can't write JASS.

Explanation
AWall does various checks to runners that have been added to the system. It periodically checks if runners are stopped, attacking, or stuck, it drops 'breadcrumb' rects behind runners to see if they backtrack, it catches runners attacking towers, etc.

When you create a runner you want wall detection on, add it to the system using AWall_AddRunner. When a player builders a tower use AWall_AddTower on it [only necessary if you use attack prevention]. When a runner reaches a waypoint, use AWall_ResetRunner [backtracking is possible after waypoints, this removes the currently dropped bread crumbs for that unit].

When it detects that a runner has been walled, it runs callbacks registered using AWall_RegisterForWalled. It sets the globals AWall_unit to the runner, and AWall_reason to the reason it believes the unit was walled. For example, if the unit was attacking, reason will be set to AWALL_REASON_ATTACKING. It is the maps job to punish the player, save the unit or whatever else the maker wants. AWall only does detection.

If a unit is/was recently snared or stunned, the wall detection will still activate, but it will have a reason set to AWALL_REASON_PREVENT. When you get PREVENT, you should usually not punish the player, but simply re-order the unit [it may have just been released and started attacking].

Code
Expand JASS:

History
None
Attached Images
File type: pngAWall.PNG (17.1 KB)
Attached Files
File type: w3xAWall beta4.w3x (51.1 KB)
07-16-2008, 02:55 AM#2
DioD
native IssuePointOrder takes unit whichUnit, string order, real x, real y returns boolean

Code:
if not IssuePointOrder(Unit,SomeRB("move"),x,y) then
call Echo("Unit cannot complete this order")
endif
07-16-2008, 03:03 AM#3
Strilanc
Quote:
Originally Posted by DioD
native IssuePointOrder takes unit whichUnit, string order, real x, real y returns boolean

Code:
if not IssuePointOrder(Unit,SomeRB("move"),x,y) then
call Echo("Unit cannot complete this order")
endif

I'm not exactly sure what your point is. Do you think IssuePointOrder will detect walls? It won't.

- Even if a unit can't reach the destination it will move to a closer point, so the order still succeeds [tested and confirmed, please don't state things like this unless you've tested them].
- Even if the order returned false if the destination wasn't reachable, units can be walled after they are ordered.
- Even if you could detect the destination becoming unreachable, juggling units only requires switching maze exits back and forth (never closing both, therefore the end is always reachable).

You _need_ backtrack detection if you want to stop juggling [*without severely interfering with players like blocking building during rounds].
08-02-2008, 12:22 AM#4
moyack
This system is simply elegant. I must confess that at the beginning I didn't understand its purpose but now that I tested it it looks great and useful, not only for Tower defense.

One thing that I noticed is this:

Collapse JASS:
function AWall_AddRunner takes unit u returns nothing
    call Runner.create(u)
endfunction

just set those functions as public and you won't need to set the prefix

Collapse JASS:
public function AddRunner takes unit u returns nothing
    call Runner.create(u)
endfunction

Do this and I'll put this submission in the right place.
08-04-2008, 04:12 PM#5
d07.RiV
Also
Collapse JASS:
        public method report takes integer reason, string reasonName returns nothing
            if .wasHeld or .isHeld and reason != AWALL_REASON_PREVENT then
                call .report(AWALL_REASON_PREVENT, reasonName + "(prevented)")
                return
            endif
            call .reset() //avoid double-catch
can be changed to
Collapse JASS:
        public method report takes integer reason, string reasonName returns nothing
            if .wasHeld or .isHeld and reason != AWALL_REASON_PREVENT then
                set reason = AWALL_REASON_PREVENT
                set reasonName = reasonName + "(prevented)"
            endif
            call .reset() //avoid double-catch
Doesn't really affect performance, just a tip.

I'll try it if I ever make a map that involves any kind of runners/creeps (I suppose it can also be used for AoS with some modifications?)
08-04-2008, 06:27 PM#6
Strilanc
It doesn't work if the runners are attackers.
08-04-2008, 06:41 PM#7
moyack
meh.

my tip is just aesthetic, so moved to scripts systems.
08-06-2008, 06:51 PM#8
D.V.D
Could this detect cliffs too?
08-06-2008, 11:12 PM#9
Strilanc
It detects when a runner is walled, whether or not it's buildings doing it.
08-07-2008, 12:10 AM#10
Kam
Could this be modified to stop submerged units from entering shallow water?
08-07-2008, 12:19 AM#11
Strilanc
What exactly do you think the system does? It detects if a runner is acting like it was walled, it doesn't look at the terrain in any way.