• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Baradé's Ray 1.0

This bundle is marked as pending. It has not been reviewed by a staff member yet.
Motivation
A simple ray spells system inspired by Ray of Frost and Disintegrate from Diablo III.
The rays can detect units, destructables and items for collisions as well as terrain height differences and pathing.
Warcraft III does not allow this by default.

This is how the Diablo III spell looks like:

The hero can still walk and attack while using ray spells with this system unlike in Diablo III.

Usage
You need to specify all options in the library RayConfig like in the demo map.
The demo map contains many example spells which you could use.
More will be added in the future.

Here is a demo video:


I have updated the system since the video and added delays for ray effects such as cyclone and resurrection as well as harvesting to make it a bit more balanced.


Features
  • Target detection for units, items and destructables.
  • Blocking by pathing and height differences.
  • Target Z detection.
  • Target unit collision size detection.
  • Hit duration per target detection.
  • Loop and target sounds.
  • Caster and target effects.
  • Mouse movement aiming.
  • Multiple different lightnings per spell.
  • Dummy support for target ability effects.

Future Work
- DONE: Polymorph/Hex Ray in the demo map.
- DONE: Neutralization Ray in the demo map.
- DONE: Charm Ray in the demo map.
- DONE: Caster and target effect with user-defined attachment points.
- DONE: Disable attacking during ray (Charm Ray etc.).
- DONE: Better aiming controls maybe while pressing shift or something where the hero only changes the direction.
- Allow one ray to hit multiple targets?
- More options to configure rays: Blocking pathing types, disallow moving/attacking, etc.
- Register destructable collision sizes for more accurate blocking/hitting.
- My issue for my own map for this system: https://github.com/tdauth/wowr/issues/2698

Credits
- Custom lightning effects by Spellbound: https://www.hiveworkshop.com/threads/spellbounds-custom-lightning-effects.292771/
Contents

Baradé's Ray 1.0 (Map)

Antares

Spell Reviewer
Level 21
Joined
Dec 13, 2009
Messages
510
I was thinking about that too. I might be able to catch and interrupt move/target orders and only change the facing and could add a boolean flag for that.
I made a spell like that. I added a second, hidden channeling ability based on Channel to the hero when the original spell is cast, then whenever a movement command is given, it is replaced with casting the hidden spell at the target location.

To get the hold-down-right-mouse-button to change direction of the laser behavior, you'd need a click-and-hold system.
 
Level 26
Joined
Feb 2, 2006
Messages
1,690
How exactly does it work in Diablo? You hold a key for the spell and then ordering with the mouse will only rotate the caster? When you release the key the spell stops? I do not need to cast a new spell when the order is given but only rotate the hero. The ray will change the direction automatically to the facing of the hero.
 

Antares

Spell Reviewer
Level 21
Joined
Dec 13, 2009
Messages
510
Hope I'm remembering this right, been ten years.

You can bind a spell to the left- and right-mouse-button or to keys. Whatever key or button you bind it to, as long as you hold it down, your character will stop and channel the laser in the direction of your mouse-cursor.

You could make it so that holding down the spell hotkey makes the hero fire it, but you have to solve the issue that different players have different hotkey layouts.
 
Level 26
Joined
Feb 2, 2006
Messages
1,690
If you keep a key pressed for a spell it will be cast n times again and again by Warcraft III. I could just add a timer like 2 seconds or 1 second which checks if you still restart casting it (holding the key down). Then I do not need to know the hotkey but it would be limited to the spell's hotkey.

For attacks I could try adding mouse bindings but it will take some time to add this.

At least I got an option which stops the hero and only changes the hero's facing when ordering movement somewhere.

edit:
Update:
  • Frost Ray, Fire Ray and Frost and Fire Ray spells require holding their key and allow aiming with the mouse cursor like in Diablo III now.
  • Fix exploding barrels.
  • Increase the damage by ray spells.
  • Escape key allows reviving and refilling your heroes.
  • Refactoring and some optimization of code.
  • Library requires MouseUtils.
  • Custom libraries TreeUtils and MathUtils as clear requirements for the system.
 
Last edited:
These massive if/then trees is not ideal. Why not store valid abilities in a hashtable so that this check is O(1)? It would also condense a lot of your code.
JASS:
public function IsValidAbility takes integer abilityId returns boolean
    if (abilityId == FROST_RAY) then
        return true
    elseif (abilityId == FIRE_RAY) then
        return true
    elseif (abilityId == HOLY_RAY) then
        return true
    elseif (abilityId == HARVEST_RAY) then
        return true
    elseif (abilityId == LOOT_RAY) then
        return true
    elseif (abilityId == WATER_RAY) then
        return true
    elseif (abilityId == DRAIN_RAY) then
        return true
    elseif (abilityId == FROST_AND_FIRE_RAY) then
        return true
    elseif (abilityId == CHAIN_RAY) then
        return true
    elseif (abilityId == MANA_RAY) then
        return true
    elseif (abilityId == RAISE_RAY) then
        return true
    elseif (abilityId == POISON_RAY) then
        return true
    elseif (abilityId == CHARM_RAY) then
        return true
    elseif (abilityId == NEUTRALIZATION_RAY) then
        return true    
    elseif (abilityId == HEX_RAY) then
        return true
    elseif (abilityId == RESURRECTION_RAY) then
        return true
    elseif (abilityId == WIND_RAY) then
        return true
    endif
    return false
endfunction
 

Antares

Spell Reviewer
Level 21
Joined
Dec 13, 2009
Messages
510
It could be worse :plol:

Yea, you can use a hashtable for the checks and for the effect calls a function interface. I also think that you should make it easy for the user to define their own on-hit callback. I'm thinking that the vast majority of people will want to use a damaging ray with flashy special effects attached to it and maybe some secondary effects like debuffs etc.
 
Level 26
Joined
Feb 2, 2006
Messages
1,690
I can provide some kind of struct RayType with function callbacks. Need some more time/work. It just grew this way.

For the moment, you just have to modify for example:

JASS:
public function OnHitUnit takes unit caster, unit target, integer abilityId, real duration returns nothing

I want to support multiple abilities per ray type in the future since you could have different hero/unit/item abilities with the same ray times.
I would need some function like
JASS:
function IsLootRay takes integer abilityId returns boolean
with the current version.

I can refactor it using some RayType struct and making the T struct public as RayData or something:

JASS:
struct RayData // exists already as struct T in library Ray
      integer abilityId
      unit caster
      unit target
      real duration

      ...

endstruct

function interface OnHitUnit takes RayData r returns nothing

struct RayType
      string casterEffect
      string hitEffect
      boolean mouseAiming
      OnHitUnit onHitUnit

      ...

endstruct

function AddRayType takes integer abilityId, RayType t returns nothing


I was also wondering if there were any standardized TreeUtils and MathUtils on Hive/which are used in other systems rather than my own libs.
 
Last edited:
Top