1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Ride into the sunset with the 32nd Modeling Contest.
    Dismiss Notice
  5. This adventure has come to an end. Congratulate our heroes in the 16th Mini Mapping Contest Results.
    Dismiss Notice
  6. From the gates of hell, the 5th Special Effect Contest Results have emerged.
    Dismiss Notice
  7. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  8. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Spell] Bane of Evil

Submitted by stn
This bundle is marked as pending. It has not been reviewed by a staff member yet.
A fancy arrow that knocks back enemies and deals some damage.

The reason I am uploading this is because the number of examples for Wurst is scarce.

The entire spell is generated using Wurst.

To test the spell:
  1. Download the map directly from the Hiveworkshop
To edit the spell:
  1. Download the relevant files from the relevant Github page
  2. Create a new project using WurstSetup
  3. Copy the Wurst folder and the example map to the new project
The following files make up the code (Github page version 4):

[Wurstbin] AbilityTooltipGenerator is used to generate tooltips (by Frotty)
[Wurstbin] Ranger is used to add the ability to the test hero
[Wurstbin] BaneOfEvil contains the spell mechanics
[Wurstbin] BaneOfEvil_config allows the user to configure the spell parameters
[Wurstbin] Missile demonstrates the use of a class for missiles

The spell demonstrates the following packages from the Wurst standard library:
  • Assets
  • AbilityTooltipGenerator
  • ChannelAbilityPreset
  • ClosureEvents
  • ClosureForGroups
  • Knockback3
  • TimerUtils
Contents

DefaultName (Map)

Reviews
Frotty
@stn Good job so far :thumbs_up: Few notes: Shouldn't master be the recent version and old on branch? Otherwise no way to pull via setup tool i think. In Missile instead of private static let clock = CreateTimer() You could just use the...
mori
Spell Review: Nice spell. Demonstrates very well how easy it is to make a spell like this using Wurst. One small nitpick: the missile has a maximum range, but it only travels up to the cast point. I think it'd make more sense if it travelled its...
  1. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,362
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
  2. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,732
    Resources:
    18
    Maps:
    1
    Spells:
    11
    Tutorials:
    6
    Resources:
    18
    This is minor, but you do not need @configurable before every line, especially since there are no exceptions.

    It would be less bloat to juse
    @configurable
    // vars here
    @endconfigurable
     
  3. Cokemonkey11

    Cokemonkey11

    Wurst Reviewer

    Joined:
    May 9, 2006
    Messages:
    3,237
    Resources:
    18
    Tools:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    2
    JASS:
    7
    Resources:
    18
    What is `Missile` really for? Should it be in the standard library? Is it a dependency with its own git uri?

    for comparing distance between points, prefer distanceToSq when appropriate

    `KNOCKBACK_ANGLE_AIR` what are the units?

    Code seems fine overall. @Frotty FYI
     
  4. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,362
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7

    Spell Review:



    Spell Description:


    • It might be helpful to point out the target type of the ability, namely either a unit target, point target, both, or instant (no target).
    • Description on what the ability does can be improved, such as the amount of damage dealt, knockback strength, cooldown, etc.

    Spell Mechanics:


    • Pertaining to the first point raised in the Spell Description, the target type of the spell is point-targeted. This has not been referenced in the description as to what the spell does. (in HIVE) (Malus of 0.15 points)

    Spell Logic:


    • Quoting the appropriate reviewers for Wurst resources:

    • CokemonKey11:

      Calculated total malus points by MyPad based on the quote above: (0.45 points)

    Rating:



    4.4/5.0
     
  5. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    > The reason I am uploading this is because the number of examples for Wurst is scarce.

    Nice :) Many people said they would make spells and more, but never did!

    The wurstbin links could be a bit more prevalent. At first I thought they were resource links or something else.
    Also, as coke said, should probably make a git repo so this spells can be imported as dependency?

    The "setup" snippet should probably contain a package definition. Also changing the gravity might not be ideal if people just copy it into their maps.

    I think you are mixing something up. The @configurable annotation has actual purpose in wurst, indicating which variables can be configured, otherwise they will throw a warning.

    @MyPad

    I would suggest waiting at least a few days for a response from OP before final review? Seems a bit early to me, when feedback has just been provided.
     
  6. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,732
    Resources:
    18
    Maps:
    1
    Spells:
    11
    Tutorials:
    6
    Resources:
    18
    @Frotty
    Then just change the annotation to "config" or something I suppose
    Unless I am completely wrong and annotations are not glorified comments (I know compiletime has functionality but does configurable actually do something?)

    Me personally, I would rather do:
    // Config
    stuff
    // End Config

    Rather than having 20 configurable keywords, to me it is too much bloat, especially in this case where every single variable is used for config so there is no confusion regarding what to change and not.
     
  7. stn

    stn

    Joined:
    Dec 27, 2018
    Messages:
    4
    Resources:
    0
    Resources:
    0
    Update: added a new version that is more tailored towards the style that is used in the library packages.

    Also:
    • Removed the @configurable part
    • Added units for KNOCKBACK_ANGLE_AIR (degrees)
    • Made wurstbin links more visible
    • Added a link to a Github repository containing the relevant files
    • Added an installation instruction
    That's it for now.
     
  8. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    @stn

    Good job so far :thumbs_up:
    Few notes:

    • Shouldn't master be the recent version and old on branch? Otherwise no way to pull via setup tool i think.
    • In Missile instead of
      private static let clock = CreateTimer()
      You could just use the TimedLoopModule
    • In Missile
      private unit u
      must be initialized "= null" otherwise recycled objects could have residual references
    • Don't write
      static function create
      when you can just use constructors. They exist for a reason.
    • You are still using
      distanceTo
      when you could use
      distanceToSq
      from what I see
    • Often you don't use type inference, prefer
      let
      and
      var
    • In general brush up on coding conventions: WurstScript • Manual
    • An improvement could be to add multiple levels and use Level-Closures for the config variables
    You misunderstood - the config variable should be of type angle, e.g. `0 .fromDeg()` by default.
    Then the user also has to supply an angle, thus avoiding any possible confusion between degrees/radians.
    Right now you still have the problem that an angle in radians will produce unexpected results.

    Cheers

    @config is used to overwrite @configurable variables. Otherwise it will throw a warning.
     
  9. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    Very nice! Looks close to best practice now :)
    A few things still stand imho:
    • Keep newest version on master branch of repo so it can be used as dependency more easily
    • Hide older version pastes in a spoiler
    Presentation-wise a gif showing the spell in action would be cool and you should add an image of the generated tooltip.
    I can provide the gif.

    Cheers :thumbs_up:

    edit:
    maybe a few mroe things :ugly:
    • show AoE target image (it's option on ChannelPreset) I expected the arrow to go max distance.
    • Improve the test map to add terrain height differences, cliffs, trees. It will be good to see the arrow interact with it
    Thanks again :thumbs_up:
     
    Last edited: Jan 22, 2019
  10. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,362
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
  11. mori

    mori

    Joined:
    Jun 13, 2016
    Messages:
    434
    Resources:
    2
    Tools:
    1
    Tutorials:
    1
    Resources:
    2
    Sure. I'll write a review during the weekend, then.
     
  12. mori

    mori

    Joined:
    Jun 13, 2016
    Messages:
    434
    Resources:
    2
    Tools:
    1
    Tutorials:
    1
    Resources:
    2
    Spell Review:
    Nice spell. Demonstrates very well how easy it is to make a spell like this using Wurst.
    One small nitpick: the missile has a maximum range, but it only travels up to the cast point. I think it'd make more sense if it travelled its entire maximum length regardless of the cast point.

    Code Review:
    I think this is ready for approval, just a few things that I'd like changed:
    1. In `BaneOfEvil_config.wurst`, change `let` bindings to `constant` bindings.
    2. In `BaneOfEvil.wurst`:
      Change
      Code (Text):

      let missile = new Missile(FX_MISSILE, caster.getPos3Fly(), target)
      missile
      ..setSpeed(MISSILE_SPEED)
      ..setHeight(MISSILE_HEIGHT)
      ..setScale(FX_MISSILE_SCALE_BASE + FX_MISSILE_SCALE_LVL * caster.getAbilityLevel(abilId))
      ..setTrail(FX_TRAIL)
      ..setTrailAttach(FX_TRAIL_ATTACH)
      ..onHit(-> explode(caster, target))
       
      to
      Code (Text):

      new Missile(FX_MISSILE, caster.getPos3Fly(), target)
      ..setSpeed(MISSILE_SPEED)
      ..setHeight(MISSILE_HEIGHT)
      ..setScale(FX_MISSILE_SCALE_BASE + FX_MISSILE_SCALE_LVL * caster.getAbilityLevel(abilId))
      ..setTrail(FX_TRAIL)
      ..setTrailAttach(FX_TRAIL_ATTACH)
      ..onHit() ->
          explode(caster, target)
       
      This is slightly more idiomatic.

      Change
      Code (Text):

      static let abilId = compiletime(ABIL_ID_GEN.next())
       
      to
      Code (Text):

      static constant ABIL_ID = compiletime(ABIL_ID_GEN.next())
       
    3. In `Missile.wurst`

      Make sure to destroy the callback object in `ondestroy`:

      Code (Text):

          ondestroy
              art.destr()
              cb.callback()
              destroy cb
       
      Not doing so will cause a class instance leak for the closure object.

      Use `real.atan2(y)` vs using the Atan2 native directly.
    Status:
    Awaiting Update
     
  13. stn

    stn

    Joined:
    Dec 27, 2018
    Messages:
    4
    Resources:
    0
    Resources:
    0
    What's the idea behind this?
     
  14. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    The idea is that the convention is to use 'constant' for globals, but let is okay too, they are functionally the same.
     
  15. stn

    stn

    Joined:
    Dec 27, 2018
    Messages:
    4
    Resources:
    0
    Resources:
    0
    The aim is to have control over the position where it lands (a target image has been added).

    Other than that the code has been changed according to your comments. Also, atan2 has been replaced with getAngle.
     
    Last edited: Jan 5, 2020
  16. MyPad

    MyPad

    Spell Reviewer

    Joined:
    May 9, 2014
    Messages:
    1,362
    Resources:
    7
    Models:
    1
    Icons:
    2
    Spells:
    3
    JASS:
    1
    Resources:
    7
    So, @Frotty, is this ready for approval?
     
  17. Frotty

    Frotty

    Wurst Reviewer

    Joined:
    Jan 1, 2009
    Messages:
    1,473
    Resources:
    11
    Models:
    3
    Tools:
    1
    Maps:
    5
    Tutorials:
    1
    Wurst:
    1
    Resources:
    11
    Probably is.

    Few more things
    • Don't hide repo link behind "relevant files" so one can more easily use package manager to install it, e.g. `grill install StN-NL/wurstscript-spell-bane-of-evil`
    • AbilityToooltipGenerator should probably just be a dependency instead of copy pasted into this repo
    • The repo should be a valid wurst project, not just map & .wurst files
    • Change "DefaultName" of example map and don't just upload "WurstRunMap"
    These steps:
    [​IMG]
    Should be "Either use `grill install`or the WurstSetup to update the downloaded project".
    Also why is there only "Test" and "Edit" ? Should be "Use" via wurst.build dependency first and foremost.

    e: That actually brings up another problem. "BaneOfEvil_config.wurst" is not a config package, yet named _config. The actual _config package would be in the user's project, configuring your "Config" package which should have variables annotated @configurable.
     
    Last edited: Jan 9, 2020