1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Seek unity between the elements in the 22nd Terraining Contest Poll.
    Dismiss Notice
  3. Seize the moment! The 18th Mini Mapping Contest has commenced.
    Dismiss Notice
  4. Gather 'round - the 20th Icon Contest Poll is out.
    Dismiss Notice
  5. The heavens smile on the old faithful. The 16th Techtree Contest has begun.
    Dismiss Notice
  6. 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.

Revivable Units v1.3.3b

Submitted by loktar
This bundle is marked as approved. It works and satisfies the submission rules.
  • Toggle any unit type per player or for all players
  • Option to allow normal training for other players
  • Option to show a configurable dissipate effect on death (default)
  • Show a configurable revive effect
  • Revivable unit types are limited to one unit (optional)

API
GUI

Note that in order to use the GUI configuration, you also need all the triggers in the "Revive Config Functions" category, as well as all the variables and their initial values.
Configure Unit-Types

NOTE: Don't forget that units have to be added to a building (e.g. Altar) manually in order to build them.
  • SetUnitsGUI
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Footman for All Players --------
      • Set UnitType = Footman
      • Set Players = AllPlayers
      • Trigger - Run AddType <gen> (ignoring conditions)
      • -------- Grunt for All Players except Player 2 (blue) --------
      • Set UnitType = Grunt
      • Set Players = AllPlayers
      • Trigger - Run AddType <gen> (ignoring conditions)
      • Set Players = (Player number of Player 2 (Blue))
      • Trigger - Run RemoveType <gen> (ignoring conditions)
      • -------- Ghoul for Player 1 (red) --------
      • Set UnitType = Ghoul
      • Set Players = (Player number of Player 1 (Red))
      • Trigger - Run AddType <gen> (ignoring conditions)
      • -------- Ghoul available normally for other players --------
      • Set AllowAll = True
      • Trigger - Run AllowNormalTraining <gen> (ignoring conditions)
      • -------- Archer for Player 2 (blue) --------
      • Set UnitType = Archer
      • Set Players = (Player number of Player 2 (Blue))
      • Trigger - Run AddType <gen> (ignoring conditions)
      • -------- Fel Stalker for Player 1 & 2 (red & blue) --------
      • Set UnitType = Fel Stalker
      • Set Players = (Player number of Player 1 (Red))
      • Trigger - Run AddType <gen> (ignoring conditions)
      • Set Players = (Player number of Player 2 (Blue))
      • Trigger - Run AddType <gen> (ignoring conditions)
      • -------- Fel Stalker can be trained more than once for Player 1 (red) --------
      • Set Players = (Player number of Player 1 (Red))
      • Set AllowMultiple = True
      • Trigger - Run AllowMultiple <gen> (ignoring conditions)
      • -------- Priest (Blood Mage model) for Player 1 (red) - using Dissipate animation --------
      • Set UnitType = Priest
      • Set Players = (Player number of Player 1 (Red))
      • Trigger - Run AddType <gen> (ignoring conditions)
      • Trigger - Run HasDissAnim <gen> (ignoring conditions)


Configure Dissipate

NOTE: Anything left to default can be deleted, since defaults are already set in the code. Only included here for demonstration.
  • ConfigureDissipateGUI
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Configure the Dissipate Effect --------
      • -------- -- These are the default settings --------
      • Set confDelay = 3.00
      • Set confOpacity = 200
      • Set confDuration = 2.00
      • Set confIncrement = 0.03
      • Set confHeight = 530.00
      • Trigger - Run ConfigureDissipate <gen> (ignoring conditions)
      • -------- Set Dissipate Effect per race --------
      • -------- -- These are the default settings --------
      • -------- -- Only Undead has a dissipate model w/ sound --------
      • Set Race = Undead
      • Set EffectString = Objects\Spawnmodels\Undead\UndeadDissipate\UndeadDissipate.mdl
      • Set Sound = No sound
      • Trigger - Run ConfigureDissSFX <gen> (ignoring conditions)
      • -------- -- Rest has no dissipate model, so setup sound --------
      • Set Race = Human
      • Set EffectString = <Empty String>
      • Set Sound = HumanDissipate1 <gen>
      • Trigger - Run ConfigureDissSFX <gen> (ignoring conditions)
      • Set Race = Orc
      • Set EffectString = <Empty String>
      • Set Sound = OrcDissipate1 <gen>
      • Trigger - Run ConfigureDissSFX <gen> (ignoring conditions)
      • Set Race = Night Elf
      • Set EffectString = <Empty String>
      • Set Sound = NightElfDissipate1 <gen>
      • Trigger - Run ConfigureDissSFX <gen> (ignoring conditions)
      • -------- -- Demon doesn't have its own diss sound --------
      • Set Race = Demon
      • Set EffectString = <Empty String>
      • Set Sound = HumanDissipate1 <gen>
      • Trigger - Run ConfigureDissSFX <gen> (ignoring conditions)
      • -------- -- 11 possible races (1 - Human, 2 - Orc, 3 - Undead, 4 - Nightelf, 5 - Demon, 7 - Other, 11 - Naga) --------
      • For each (Integer A) from 6 to 11, do (Actions)
        • Loop - Actions
          • Custom script: set udg_Race = ConvertRace(bj_forLoopAIndex)
          • Set EffectString = <Empty String>
          • Set Sound = HumanDissipate1 <gen>
          • Trigger - Run ConfigureDissSFX <gen> (ignoring conditions)


Configure Revive

NOTE: Anything left to default can be deleted, since defaults are already set in the code. Only included here for demonstration.
  • ConfigureReviveGUI
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Set Revive Effect per race --------
      • -------- -- These are the default settings --------
      • -------- -- Revive effects have sound attached, except Demon --------
      • Set Race = Human
      • Set EffectString = Abilities\Spells\Human\ReviveHuman\ReviveHuman.mdl
      • Set Sound = No sound
      • Trigger - Run ConfigureRevSFX <gen> (ignoring conditions)
      • Set Race = Orc
      • Set EffectString = Abilities\Spells\Orc\ReviveOrc\ReviveOrc.mdl
      • Set Sound = No sound
      • Trigger - Run ConfigureRevSFX <gen> (ignoring conditions)
      • Set Race = Undead
      • Set EffectString = Abilities\Spells\Undead\ReviveUndead\ReviveUndead.mdl
      • Set Sound = No sound
      • Trigger - Run ConfigureRevSFX <gen> (ignoring conditions)
      • Set Race = Night Elf
      • Set EffectString = Abilities\Spells\NightElf\ReviveNightElf\ReviveNightElf.mdl
      • Set Sound = No sound
      • Trigger - Run ConfigureRevSFX <gen> (ignoring conditions)
      • Set Race = Demon
      • Set EffectString = Abilities\Spells\Demon\ReviveDemon\ReviveDemon.mdl
      • Set Sound = ReviveHuman <gen>
      • Trigger - Run ConfigureRevSFX <gen> (ignoring conditions)
      • -------- -- 11 possible races (1 - Human, 2 - Orc, 3 - Undead, 4 - Nightelf, 5 - Demon, 7 - Other, 11 - Naga) --------
      • For each (Integer A) from 6 to 11, do (Actions)
        • Loop - Actions
          • Custom script: set udg_Race = ConvertRace(bj_forLoopAIndex)
          • Set EffectString = Abilities\Spells\Human\ReviveHuman\ReviveHuman.mdl
          • Set Sound = No sound
          • Trigger - Run ConfigureRevSFX <gen> (ignoring conditions)


Configure Abilities

NOTE: Both abilFly AND abilSelect must be set before running ConfigureAbilities. If both are left to default, no need to set them here as long as ConfigureAbilities is not run. The default meld abilities do not need to be added here, so they can be deleted. They are only included here to demonstrate how to add custom meld abilities.
  • ConfigureAbilitiesGUI
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- These are the default settings --------
      • -------- Set Fly Ability (used to lift unit during dissipate) --------
      • Set abilFly = Storm Crow Form
      • -------- Set Locust Ability (used to make unit unselectable) --------
      • Custom script: set udg_abilSelect = 'Aloc'
      • Trigger - Run ConfigureAbilities <gen> (ignoring conditions)
      • -------- Add Meld Abilities (removed on death) --------
      • Set abilMeld = Shadow Meld
      • Trigger - Run RemoveAbilOnDeath <gen> (ignoring conditions)
      • Set abilMeld = Shadow Meld (Instant)
      • Trigger - Run RemoveAbilOnDeath <gen> (ignoring conditions)
      • Set abilMeld = Shadow Meld (Akama)
      • Trigger - Run RemoveAbilOnDeath <gen> (ignoring conditions)




JASS

You can use these functions either in a "Custom script" or in plain JASS custom text.
For JASS configuration, you do not need any of the triggers in the "Revive Config Functions" category, nor any of the variables.

Configure Unit-Types

NOTE: Don't forget that units have be added to a building (e.g. Altar) manually in order to build them.
  • SetUnitsJASS
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Footman for All Players --------
      • Custom script: call SetTypeRevivable('hfoo', 16)
      • -------- Grunt for All Players except Player 2 (blue) --------
      • Custom script: call SetTypeRevivable('ogru', 16)
      • Custom script: call UnsetTypeRevivable('ogru', 1)
      • -------- Ghoul for Player 1 (red) --------
      • Custom script: call SetTypeRevivable('ugho', 0)
      • -------- Ghoul available normally for other players --------
      • Custom script: call AllowNormalTraining('ugho', true)
      • -------- Archer for Player 2 (blue) --------
      • Custom script: call SetTypeRevivable('earc', 1)
      • -------- Fel Stalker for Player 1 & 2 (red & blue) --------
      • Custom script: call SetTypeRevivable('nfel', 0)
      • Custom script: call SetTypeRevivable('nfel', 1)
      • -------- Fel Stalker can be trained more than once for Player 1 (red) --------
      • Custom script: call AllowMultiple('nfel', 0, true)
      • -------- Priest (Blood Mage model) for Player 1 (red) - using Dissipate animation --------
      • Custom script: call SetTypeRevivable('hmpr', 0)
      • Custom script: call SetTypeHasDissipate('hmpr', true)


Configure Dissipate

NOTE: Anything left to default can be deleted, since defaults are already set in the code. Only included here for demonstration.
  • ConfigureDissipateJASS
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Configure the Dissipate Effect --------
      • -------- -- These are the default settings --------
      • Custom script: call ConfigureDissipate(3, 200, 2, 0.03, 530)
      • -------- Set Dissipate Effect per race --------
      • -------- -- These are the default settings --------
      • -------- -- Only Undead has a dissipate model w/ sound --------
      • Custom script: call ConfigureDissSFX(RACE_UNDEAD, "Objects\\Spawnmodels\\Undead\\UndeadDissipate\\UndeadDissipate.mdl", null)
      • -------- -- Rest has no dissipate model, so setup sound --------
      • Custom script: call ConfigureDissSFX(RACE_HUMAN, null, gg_snd_HumanDissipate1)
      • Custom script: call ConfigureDissSFX(RACE_ORC, null, gg_snd_OrcDissipate1)
      • Custom script: call ConfigureDissSFX(RACE_NIGHTELF, null, gg_snd_NightElfDissipate1)
      • -------- -- Demon doesn't have its own diss sound --------
      • Custom script: call ConfigureDissSFX(RACE_DEMON, null, gg_snd_HumanDissipate1)
      • -------- -- 11 possible races (1 - Human, 2 - Orc, 3 - Undead, 4 - Nightelf, 5 - Demon, 7 - Other, 11 - Naga) --------
      • For each (Integer A) from 6 to 11, do (Actions)
        • Loop - Actions
          • Custom script: call ConfigureDissSFX(ConvertRace(bj_forLoopAIndex), null, gg_snd_HumanDissipate1)


Configure Revive

NOTE: Anything left to default can be deleted, since defaults are already set in the code. Only included here for demonstration.
  • ConfigureReviveJASS
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Set Revive Effect per race --------
      • -------- -- These are the default settings --------
      • -------- -- Revive effects have sound attached, except Demon --------
      • Custom script: call ConfigureRevSFX(RACE_HUMAN, "Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl", null)
      • Custom script: call ConfigureRevSFX(RACE_ORC, "Abilities\\Spells\\Orc\\ReviveOrc\\ReviveOrc.mdl", null)
      • Custom script: call ConfigureRevSFX(RACE_UNDEAD, "Abilities\\Spells\\Undead\\ReviveUndead\\ReviveUndead.mdl", null)
      • Custom script: call ConfigureRevSFX(RACE_NIGHTELF, "Abilities\\Spells\\NightElf\\ReviveNightElf\\ReviveNightElf.mdl", null)
      • Custom script: call ConfigureRevSFX(RACE_DEMON, "Abilities\\Spells\\Demon\\ReviveDemon\\ReviveDemon.mdl", gg_snd_ReviveHuman)
      • -------- -- 11 possible races (1 - Human, 2 - Orc, 3 - Undead, 4 - Nightelf, 5 - Demon, 7 - Other, 11 - Naga) --------
      • For each (Integer A) from 6 to 11, do (Actions)
        • Loop - Actions
          • Custom script: call ConfigureRevSFX(ConvertRace(bj_forLoopAIndex), "Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl", null)


Configure Abilities

NOTE: Anything left to default can be deleted, since defaults are already set in the code. Only included here for demonstration.
  • ConfigureAbilitiesJASS
    • Events
    • Conditions
    • Actions
      • -------- These are the default settings --------
      • -------- Add Meld Abilities (removed on death) --------
      • Custom script: call RemoveAbilOnDeath('Ashm')
      • Custom script: call RemoveAbilOnDeath('Sshm')
      • Custom script: call RemoveAbilOnDeath('Ahid')
      • -------- Set Fly Ability (used to lift unit during dissipate) --------
      • Custom script: call SetFlyAbil('Arav')
      • -------- Set Locust Ability (used to make unit unselectable) --------
      • Custom script: call SetSelectAbil('Aloc')




Test Map Info
  • Chat commands:
    • "kill footman", "kill grunt", "kill ghoul", "kill archer", "kill stalker", "kill priest" and "kill hero".
  • Use the "warpten" cheat to speed up training
  • There are some enemies north-west of the starting location

Thanks to BPower, Bribe, DracoL1ch, KILLCIDE, PurgeandFire, Wietlol for their help.

Changelog

1.3.3b
  • Fixed death messages still being displayed when AllowMultiple enabled
1.3.3
  • Added function AllowMultiple which allows players to train multiple units of a revivable type (and disables death message)
1.3.2
  • 24-player support
1.3.1
  • Fixed a bug that caused the dummy unit to engage enemies instead of playing the death/dissipate sequence (by pausing it)
  • GetPlayerColor renamed to GetPlayerColorString (GetPlayerColor is a native function)
1.3
  • Overhauled dissipate and revive sound and effects (code & config)
  • AllowAllPlayers renamed to AllowNormalTraining
  • AddMeldAbil renamed to RemoveAbilOnDeath
  • Dying unit is now hidden instead of removed
1.2.5
  • Fixed potential leak in Dissipate_Effect
  • Using player variable instead of calling Player(iPlayer) twice in InitRevivable
1.2.4
  • Changed default values for dissipate effect
  • No longer playing Dissipate sound when unit-type has dissipate animation (dissipate animation should have the sound effect in the model)
1.2.3
  • Small changes for very slightly increased efficiency
  • Check for valid player number in IsTypeRevivable (-1 to 16) and SetTypeRevivable (0 to 16)
1.2.2
  • Renamed dissipate configuration variables ("hard-coded" version: made these constants)
  • Replaced revTypes loop with GetTypeId() in several functions
  • Several functions now return boolean for success/failure
  • SetTypeHasDissipate: now checks if unit-type is present in revTypes
1.2.1
  • New global constant: ANY_P (any player = -1)
  • IsTypeRevivable: added ability to check for any player (ANY_P)
  • UnsetTypeRevivable: fixed not being able to unset all players when type not set for all players (i.e. can now be used to unset type when any number of players is set for it)
  • "Hard-coded" version: removed unused local variable
  • Added SetTypeHasDissipate function
1.2
  • Added configuration for effects, sounds and abilities
  • Added GUI configuration
1.1.1
  • Added GetTypeIndex to eliminate double code
  • Renamed some variables
  • Improved readability a bit: ALL_P = bj_MAX_PLAYER_SLOTS & INDEX_P = ALL_P + 1
  • Made opacityIncrement update in ConfigureDissipate()
  • Removed adding of Banish ability leftover from testing
1.1.0
  • Renamed MakeTypeRevivable to SetTypeRevivable
  • Added UnsetTypeRevivable
  • Renamed/redesigned MakeTypeExclusive to AllowAllPlayers
  • Improved unittype/player (-> better (Un)SetTypeRevivable, IsTypeRevivable, etc) storage a lot
  • Replaced TeamColor array with function
1.0.1
  • Renamed MakeUnitRevivable to MakeTypeRevivable
  • IsRevivable -> IsTypeRevivable
  • Added MakeTypeExclusive
  • Some improvements to MakeTypeRevivable
  • Some other improvements


Keywords:
revive, dissipate, unit, revivable, hero
Contents

Revivable Units test (Map)

Reviews
Moderator
20:23, 22nd Mar 2016 BPower: Fair enough. Approved with a rating of useful. Think about what I said concerning race handle ids. I feel it's a bit limitating that you can only revive one unit of a specific type id, no matter how many units of...
  1. 20:23, 22nd Mar 2016
    BPower:
    Fair enough. Approved with a rating of useful.

    Think about what I said concerning race handle ids.

    I feel it's a bit limitating that you can only revive one unit of a specific type id, no matter how many units of that type id died.
     
  2. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,638
    Resources:
    3
    Spells:
    3
    Resources:
    3
    Nice stuff here.
    Code is very neat and well readable.

    Havent tested it in-game but a few things to improve:

    - TriggerAddAction -> TriggerAddCondition
    Conditions are faster because actions create a new thread per action, conditions do not really care about them so do not have a few things... for example TriggerSleepAction() wont work in conditions.
    However, because you wont be using any of those things, you can just place your actions inside a condition.
    Also, place everything that should run on a trigger in one function, so you only have to add one condition to each trigger at max.

    -
    local location dLoc = GetUnitLoc(dyingUnit)

    You dont need the location if you use coordinates (aka GetUnitX(), GetUnitY()).
    So CreateUnitAtLoc would be CreateUnit.

    - Hashtable -> Table or TimerUtils
    You use a hashtable but do not use very much of it.
    It is recommended to use Table if you want to stick to a hashtable like that (you can make it be optional with static ifs if you dont want to force Table as a requirement).
    You do have to use integers like 0, 1, 2 etc instead of 'unit' and 'opac'.
    You can make global constants with names like "TABLE_ROW_UNIT" and "TABLE_ROW_OPACITY" and set those to 0 and 1 so you can still know what those rows are for.
    An alternative to Table would be TimerUtils and arrays.
    You will have to use an allocater to make indices and an array for the units and for the opacity, then you can remove the hashtable from your list and use the one by TimerUtils.
    This will also slightly improve timer allocation/deallocation.

    - Effects & sound paths -> configurable
    This is not really required but it could be usefull to make these configurables... maybe.

    -
    if(revUnits[iSize] == wUnit and revPlayers[iSize] == iPlayer+1) then

    You may want to keep track of how many units are used by the players... but its not really necessary.
     
  3. Arad MNK

    Arad MNK

    Joined:
    Dec 11, 2014
    Messages:
    1,887
    Resources:
    3
    Maps:
    2
    Spells:
    1
    Resources:
    3
    You can't make a single unit revivable with this system. It only works with unit types. Maybe adding this feature would result in a higher rating.

    Maybe all the system features (Is unit Revivable? or maybe the dissipate effect) would be better to be configurable for both unit types and units.

    I can imagine configuring unit types, and then adding single unit exceptions.
     
  4. loktar

    loktar

    Model Reviewer

    Joined:
    Nov 2, 2004
    Messages:
    1,549
    Resources:
    49
    Models:
    22
    Icons:
    20
    Packs:
    1
    Tools:
    3
    Spells:
    2
    Tutorials:
    1
    Resources:
    49
    Hmm, I'm making this system for my own uses really, don't want to put more effort into it than needed :p
    But I encourage anyone to take this code, add features, and upload it to the hive.

    Nice, thanks for the feedback.
    I'm not sure how to proceed with the hashtables. I'd prefer not to use any external code if I can avoid it.
    I only chose hashtables over global vars because it's easy to attach information to a specific timer that way (thus avoiding collisions when the dissipate effect is created multiple times at once), and get rid of all that information when I'm done with it.
    I don't think there's a way to do that without hashtables (other than using Table or TimerUtils)?

    Also are these the correct downloads? :p TimerUtils, Table

    Edit: on closer inspection, Table could make unittype/players storage much simpler too with 2D arrays... considering it :D
     
    Last edited: Jan 31, 2016
  5. Wietlol

    Wietlol

    Joined:
    Aug 1, 2013
    Messages:
    4,638
    Resources:
    3
    Spells:
    3
    Resources:
    3
    We have Table here on the hive as well, remade by Bribe (NewTable) iirc.
    I dont really bother about Table because I dont use hashtables at all... at all at all :D
    So I dont really know what the difference is between Table and NewTable... you have to search that for yourself.

    TimerUtils is correct.

    "Hmm, I'm making this system for my own uses really"

    There are two kinds of resources...
    1, The ones that do what you want.
    2, The ones that do what other people want.
    ... 3, Those who dont do what anyone wants.

    Making things for own usage makes things much simpler because you only have to care about the things you care about.
    Making things for public usage requires you to search for all related information, use the latest techniques to make it work in the best way and make it as efficient and readable as possible... and then there are the one thing I hate... configurables :D

    None is really better than the other... except that 1 and 2 are both better than 3 :D
    It is just what you are using/making it for.
    If you have your own project or something like that, then there might be some serious systems that are really useless for public usage but are a requirement to make the map work. You may eventually end up publishing them afterwards.
     
  6. loktar

    loktar

    Model Reviewer

    Joined:
    Nov 2, 2004
    Messages:
    1,549
    Resources:
    49
    Models:
    22
    Icons:
    20
    Packs:
    1
    Tools:
    3
    Spells:
    2
    Tutorials:
    1
    Resources:
    49
    Oh yeah, I agree, I have been adding things that I don't really need, i.e. all the configurables (which I don't like either :p). Don't even really need a function to make unit types revivable, as it would be much easier to just do it manually for every unit type I need. But when it comes to adding features, I'll leave that up to other people who want to do that :p

    I'm sharing this for two reasons: 1) sharing is caring :D and 2) the feedback you get when you submit something to be used by others is invaluable when you don't really know what you're doing :p

    Will have a look at NewTable etc and see what I can use. Mostly the ability to have 2D arrays seems attractive for storing multiple values/players per unit type. Thanks again!

    Edit: actually, I'm going to turn revPlayers into a boolean array, and reserve 17 slots per unit. I.e. the index for each player per unit will be unitIndex*17+playerId, where playerId 0-15 is just the playerId and 16 is for "all players". This is waaay easier, can't believe I didn't think of that earlier.

    So definitely won't be using Table or anything, still have to take a look at TimerUtils to see if I can be bothered with it :p seeing as the simple hashtable works quite well already

    Edit again: updated :p
     
    Last edited: Feb 1, 2016
  7. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    There exist revive systems based on resurrection on an isolated part of the map which keep you from needing to do this remove unit/create unit stuff. If a unit leaves behind no corpse, that is detectable because the resurrection order will return false.

    Regardless, what you've done with a pseudo-dissipate effect is cool. I recommend you remake this resource specifically for that.

    Sound FX string paths should be configurable. Leave nothing which could be changed by users hardcoded unless there will otherwise be functional flaws.

    Eaually, special effect string art should be configurable.

    Rawcode integers absolutely should be configurable.

    Tip: Make your configurables in GUI like I did with Damage Engine and Spell System. Easier for newer users.
     
  8. loktar

    loktar

    Model Reviewer

    Joined:
    Nov 2, 2004
    Messages:
    1,549
    Resources:
    49
    Models:
    22
    Icons:
    20
    Packs:
    1
    Tools:
    3
    Spells:
    2
    Tutorials:
    1
    Resources:
    49
    Mm, I think being able to use this on any map without having to designate a hidden part of the map to it is an advantage. I like it better this way ^^

    Sound FX & Effect configurables - will do (other than those I think everything that can be is already configurable).

    Configurables in GUI - do you mean through UDGs?
     
  9. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Actually, I just checked it again, and it revives on the spot. No hidden point on the map required. http://www.hiveworkshop.com/forums/jass-resources-412/snippet-reviveunit-186696/

    The rawcode integers must be able to be configured. They should not be hardcoded in case the user has modified those raw abilities and needs to use a copied ability in order to fulfill that role. Unlikely to happen, but the idea is to cover the predictable possibilities.

    Yes. Jass2/vJass as the base of the system, but with a separate GUI trigger for the configurable things. This way, for people to use your system they need no vJass knowledge.
     
  10. loktar

    loktar

    Model Reviewer

    Joined:
    Nov 2, 2004
    Messages:
    1,549
    Resources:
    49
    Models:
    22
    Icons:
    20
    Packs:
    1
    Tools:
    3
    Spells:
    2
    Tutorials:
    1
    Resources:
    49
    O rly. Will have a look at that :D

    Oh right, the abilities, mostly the meld abilities, looked over those.


    Alright, will do. Though I'm not sure how I'm gonna do that for adding units, as a function call is necessary for it. But I'll see what I can do :D

    Thanks for the feedback.
     
  11. loktar

    loktar

    Model Reviewer

    Joined:
    Nov 2, 2004
    Messages:
    1,549
    Resources:
    49
    Models:
    22
    Icons:
    20
    Packs:
    1
    Tools:
    3
    Spells:
    2
    Tutorials:
    1
    Resources:
    49
    Updated - everything is configurable either through GUI or JASS. Hope this approach is acceptable. Seems the best way to offer both GUI and JASS config in one package.

    About the ReviveUnit snippet - I don't see how I can implement that. It resurrects a unit immediately where it dies, whereas in my system you have to revive it in the altar (or another building) to revive it.
    So a dummy unit isn't of any use. The reason I need to remove the original dying unit and replace it with a new one is that you can't add the fly ability, change flying height, or change opacity on a dead unit. So I need to create a living one and "simulate" death.
     
  12. BPower

    BPower

    Joined:
    Mar 18, 2012
    Messages:
    1,709
    Resources:
    21
    Spells:
    15
    Tutorials:
    1
    JASS:
    5
    Resources:
    21
    Cool system idea.

    Correct me, but what happens if a player loses for example two or more unit of same type ( grunts ).
    Can he revive the same amount or just one?

    The following are just notes and not required for approval.

    As everything is race handle based, you could also use one array for sound / effect per race
    instead of a scalar variables per race. Handles ids:
    Code (vJASS):
    // Reference: 1 - Human, 2 - Orc, 3 - Undead, 4 - Nightelf, 5 - Demon, 7 - Other, 11 - Naga


    I don't understand why you have to replace dying units with new equal units, then kill those.
    Can you explain? I'm curious. :)
    Code (vJASS):
                    set dUnit = CreateUnit(dyingOwner, dyingTypeId, GetUnitX(dyingUnit), GetUnitY(dyingUnit), GetUnitFacing(dyingUnit))
                    call RemoveUnit(dyingUnit)


    I think that
    function AllowAllPlayers takes integer wTypeId, boolean allow returns boolean
    has a too generic function name.

    function AddMeldAbil takes integer newAbilMeld returns boolean
    . This one also.

    I think those two functions are not really necessary.
    Code (vJASS):
            //===========================================================================
            // Set Flying ability
            //===========================================================================
            function SetFlyAbil takes integer newAbilFly returns nothing
                set abilFly = newAbilFly
            endfunction

            //===========================================================================
            // Set Locus ability (unselectable)
            //===========================================================================
            function SetSelectAbil takes integer newAbilSelect returns nothing
                set abilSelect = newAbilSelect
            endfunction


    Config
    Code (vJASS):
            //===========================================================================
            // Configure dissipate effect model
            //===========================================================================
            function ConfigureDissEffect takes string wRace, string dEffect returns boolean        
                if(wRace == "human") then
                    set dEffectH = dEffect
                elseif(wRace == "orc") then
                    set dEffectO = dEffect
                elseif(wRace == "nightelf") then
                    set dEffectNE = dEffect
                elseif(wRace == "undead") then
                    set dEffectU = dEffect
                elseif(wRace == "demon") then
                    set dEffectD = dEffect
                else
                    return false
                endif
               
                return true
            endfunction

            //===========================================================================
            // Configure dissipate sound
            //===========================================================================
            function ConfigureDissSound takes string wRace, sound dSound returns boolean           
                if(wRace == "human") then
                    set dSoundH = dSound
                elseif(wRace == "orc") then
                    set dSoundO = dSound
                elseif(wRace == "nightelf") then
                    set dSoundNE = dSound
                elseif(wRace == "undead") then
                    set dSoundU = dSound
                elseif(wRace == "demon") then
                    set dSoundD = dSound
                else
                    return false
                endif
               
                return true
            endfunction

            //===========================================================================
            // Configure revive effect model
            //===========================================================================
            function ConfigureRevEffect takes string wRace, string rEffect returns boolean         
                if(wRace == "human") then
                    set rEffectH = rEffect
                elseif(wRace == "orc") then
                    set rEffectO = rEffect
                elseif(wRace == "nightelf") then
                    set rEffectNE = rEffect
                elseif(wRace == "undead") then
                    set rEffectU = rEffect
                elseif(wRace == "demon") then
                    set rEffectD = rEffect
                else
                    return false
                endif
               
                return true
            endfunction

            //===========================================================================
            // Configure revive sound
            //===========================================================================
            function ConfigureRevSound takes string wRace, sound rSound returns boolean        
                if(wRace == "human") then
                    set rSoundH = rSound
                elseif(wRace == "orc") then
                    set rSoundO = rSound
                elseif(wRace == "nightelf") then
                    set rSoundNE = rSound
                elseif(wRace == "undead") then
                    set rSoundU = rSound
                elseif(wRace == "demon") then
                    set rSoundD = rSound
                else
                    return false
                endif
               
                return true
            endfunction

    ^Consider what I said about handle ids. You may change the string argument for race.
     
    Last edited: Mar 22, 2016
  13. loktar

    loktar

    Model Reviewer

    Joined:
    Nov 2, 2004
    Messages:
    1,549
    Resources:
    49
    Models:
    22
    Icons:
    20
    Packs:
    1
    Tools:
    3
    Spells:
    2
    Tutorials:
    1
    Resources:
    49
    Thank you! :)

    If the owner of the unit has been set to revive that unit-type, only one can be revived. If the owner has not been set to revive, either he can't train the unit-type at all, or unlimited like normal if set through AllowAllPlayers().

    Hmm yeah, using arrays would be a lot better. If I'm understanding you correctly I could replace the if-statements with e.g. dSound[dRace] because e.g. RACE_HUMAN resolves to 1?
    Does the race variable type have 11 possible values? Because I thought there were only the ones I used (human/orc/undead/NE/demon).

    I can't apply vertex colouring or lift the unit with the fly ability on a corpse, so I have to create a new, living unit and play the death animation.
    Although thinking about it, I guess I could catch the unit right before it dies? But I'm not sure if that's reliable?

    Hmm, I will see if I can think of something more descriptive :p About the AddMeldAbil and SetSelectAbil, should I replace them with udg's? Because I was asked to make all abilities configurable.

    Yeah, could be a lot shorter with arrays. Same question as above though.



    Thanks for your feedback! I'll implement it as much as possible when I have some time.
     
  14. BPower

    BPower

    Joined:
    Mar 18, 2012
    Messages:
    1,709
    Resources:
    21
    Spells:
    15
    Tutorials:
    1
    JASS:
    5
    Resources:
    21
    Yes.
    Make sure you support the classic races orc/human/undead/nightelf. The others are optional.

    Mmh ok. The dummy unit for vertex color and death effect makes totally sense.
    I think it's better to hide the original unit instead of removing it upon death event.
     
  15. loktar

    loktar

    Model Reviewer

    Joined:
    Nov 2, 2004
    Messages:
    1,549
    Resources:
    49
    Models:
    22
    Icons:
    20
    Packs:
    1
    Tools:
    3
    Spells:
    2
    Tutorials:
    1
    Resources:
    49
    Thanks for approval! I will definitely implement race handle id based arrays for effects/sounds and their config functions, seems a lot better than what I have now.
    I'll see about implementing an extra "stock" array so each unit that dies adds to the amount that can be revived.

    Hiding the unit instead of deleting - because it gets erased from memory anyway when it has decayed? Makes sense.

    Edit: I'm curious, where can I find a list of all race handle ids? (1-11)? Can't find any documentation on it.
    Edit2: alright, this works quite nicely, and it's so much simpler :D
    Code (vJASS):


                    set rRace = GetHandleId(GetUnitRace(rUnit))
                       
                    if(rEffect[rRace] != null and rEffect[rRace] != "") then
                        call DestroyEffect(AddSpecialEffectTarget(rEffect[rRace], rUnit, "origin"))
                    endif
                    if(rSound[rRace] != null) then
                        set rSoundTemp = rSound[rRace]
                        call AttachSoundToUnit(rSoundTemp, rUnit)
                        call StartSound(rSoundTemp)
                        set rSoundTemp = null
                    endif
     

    still have to update the configuration stuff, and then do the rest of your feedback :p

    Edit: alright, done. Might add the possibility to revive a unit-type for each unit that dies later
     
    Last edited: Mar 23, 2016