• 🏆 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!

[vJass] Man Eating Plant 1.1b

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
Summons a Man Eating Plant with some Tendrils which will pull enemys inside. Enemys getting to near get slowed and eaten for some damage.


But this is more than just a simple spell. With its huge possibility of modification its nearly a system :p i added many option and e.g. its possible to create nearly everything within seconds ... whatever :D e.g. a Doc Oc
dococ.jpg



Version 1.0
-Uploaded

Version 1.1
- Improved Scripting
- Made the movement smoother
- Made the Configurtion block clearer
- Removed the NullFilter and added a usefull one
- Replaced the creation of some groups with a global one

Version 1.1b
- Made it 1.24 Compatible


JASS:
/////////////////////////////////////////////////////////////////////////////////////////////////
//                         Man Eating Plant v1.1b (1.24 compatible) 
//                                 Created by JonNny
//
//               °                                        Mapmaking since 2006...
//            °
//          °
//         °
//       °°°ÛÜ
//      °°X°ÛÛÛ                          ÛÛÛÛÛÛÛÛ     ÿÜÛÛÛÛÛÛÛÛÜ 
//     °°XX° ÛÛÛ        ßÛÛÛÛÛ        ÛÛÛÛÛÛÛÛÛÛÛÛ   ÛÛÛÛÛÛÛÛÛÛÛÛÛ
//     °XX ° ÛÛÛÛ         ÛÛÛÛÜ     ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ  ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
//     °XX °  ÛÛÛÛÛ        ÛÛÛÛ    ÛÛÛÛÛß    ßÛÛÛÛÛÛ  ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ  
//    °°XXX°° ÛÛÛÛÛÛÜ       ÛÛÛÜ  ÛÛÛÛÛ        ßÛÛÛÛÛ ßÛÛÛÛ    ÛÛÛÛÛÛ  
//   °°°°°°°°  ÛÛÛÛÛÛÛ      ÛÛÛÛ  ÛÛÛÛ                 ÛÛÛÛ      ÛÛÛÛÜ  
//             ÛÛÛÛÛÛÛÛ     ÛÛÛÛ  ÛÛÛÛ        ÛÛÛÛÛÛÛ  ÛÛÛÛÛÜ     ÛÛÛÛ  
//   °°°°°°°°  ÛÛÛÛÛÛÛÛÛ    ÛÛÛÛÜ  ÛÛÛÛÜ     ÛÛÛÛÛÛÛÛ   ÛÛÛÛÛÜ  ÜÛÛÛÛÛÛ  
//   °°XXXXX°   ÛÛÛÛ  ÛÛÛÜ  ÛÛÛÛÛ   ÛÛÛÛÛÛÜ    ßÛÛÛÛÛ   ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ  
//   °°XXXXX °° ÛÛÛÛ   ÛÛÛÛÜ ÛÛÛÛ °°°ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ°°° ÛÛÛÛÛÛÛÛÛÛÛÛÛß  
//   °  XXXXX °°ÛÛÛÛÛ°°°°ÛÛÛÛÛÛÛÛ°°XX ÛÛÛÛÛÛÛÛÛÛÛÛÛÛ XXX°°ÛÛÛÛÛÛÛÛÛÛÛ     ÛÛÛ
//   °°  XXXXX ÜÛÛÛÛÛÛ X ÛÛÛÛÛÛÛÛÛ XXX ÛÛÛÛÛÛÛÛÛÛÛ  XXXXXX  ÛÛÛÛÛÛÛ°      ÛÛÛ
//    °°  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°°   °°°°
//     °°   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX °°°°°X°°
//      °°°  XXXXXXXXXX  °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° XXXXXXXXXXXXXXXXX°°
//        °°°°°°°°°°°°°°°°                                  °°°°°°°°  XXXXXXX °°°
//                                                                  °°°°°° XX °°
//   ...2009 and still moving on.                                        °°°°°°°
//                                                                             °°
//
// What do you need to import this Spell:
//
// - Jass New Gen Pack
// - The Dummy Unit (with the Dummy model! look imports) ;line 77
// - Your Spell ;line 76
// - One or Two Spells for the Effect of the plant ; line 78 / 79
// The rest is optional and mainly refers to visual effects and importan values.
//
// Thanks to N-a-z-g-u-l for the Dummy model
//
//
///////////////////////////////////////////Modifications////////////////////////////////////////////////////

scope Plant initializer Init

globals    
    //Visual Modifications 
    private real   BirthStartRange            = 50    // The Range the Tendrils are created and move to their Default Position (TendrilLength * TendrilDefaultPosition , in this case it 192 . Birth Range should be smaller)
    private real   DefaultSinusHeight         = 75    // The Default Curve each Tendril has 
    private real   BirthAnimationSpeed        = 2.25  //The Speed of the Tendrils Birth animation
    private real   TendrilTargetHeight        = 24    //The Height a unit is grapped of the Tendril
    private real   PlantHeight                = 0     // The Base Height of the Plant and Tendrils , Has no Effect for the Attached Unit if CreatePlant = false
    private real   PlantSize                  = 1.80  //The Size of the created Plant , Has no Effect if CreatePlant = false
    private real   TendrilSizeReduction       = 0.06  //The Size Reduction of each Part (Tendril Size must be bigger than TendrilNuber * TendrilSizeReduction)
    private real   TendrilSize                = 1.4  //The Base size of each Tendril 
    private real   DefaultMovementSpeed       = 0.08  //The Speed of the Animation while being in the default position
    private real   DefaultMovementAmplitude   = 18    //The Amplitude of moving while being in the Default Position
    private real   TendrilStartHeight         = 12.00 // The Base height of the Dummys Parts of the Tentril
    private real   TendrilDefaultHeightGround = 125   // The Height above the Ground while beg in the Default position
    private real   TendrilDefaultHeight       = 280   // Sets the Max. Height of the Tendril while its in the default position , also affects its general height
    private real   OffsetAngle                = 0.00  // Define the angle the dummy units should have (depends on the model, some need to have turned by 90° )
    private string PlantDummyEffect           = "Doodads\\Outland\\Plants\\Outland_Plant\\Outland_Plant7.mdl"              //The Model of the Man Eating Plant
    private string PlantDummyEffect2          = "Abilities\\Spells\\NightElf\\EntanglingRoots\\EntanglingRootsTarget.mdl"  //The second Model of the Man Eating Plant
    private string TendrilDummyEffect         = "Doodads\\Ruins\\Plants\\Ruins_Flower\\Ruins_Flower0.mdl"                  //"Doodads\\Ruins\\Plants\\Ruins_Flower\\Ruins_Flower0.mdl"  //The Model of the Dummy
    private string TendrilEffect              = "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl" //The Model which is used at the creation and Destruction of the Plant
    
    //Important Tendril Modificatons
    private integer TendrilPartsNumber     = 16     // Number of Dummy units used for one Tendril , Do not forget to set the array in the Struct below too !!    
    private real    PullRange              = 60.00  //The Range a Unit is pulled to the Plant
    private real    TendrilLength          = 800.00 //The Lenght on an Tendril = Max Range it can GRAP units (look line below)
    private real    TendrilBendLenght      = 30     //The Range Tendrils can reach over the Tendril Lenght
    private real    TendrilSpeed           = 14     //The Speed the Tendrils will move
    private real    TendrilDefaultPosition = 0.24   // The distance of the DefaulrPosition from the Attachd Unit (depends on the max. Range (TendrilLenght*TendrilDefaultPosition), number must be between 0.01 and 1.00
                                                    // It also sets the Min. distance the unit has to reach untill it can be grapped , in this case it is : 800 * 0.24 = 192 Range
    
    //General Modification
    private integer HeroAbility = 'A000' //The Abiliy which shoudl Trigger this
    private integer DummyID     = 'h001' // The Dummy Unit
    private integer PlantSkill  = 'A001' //The Plants Damage Spell
    private integer PlantSkill2 = 'A002' //The Plants Slow Skill
    private real    TimerPeriod = 0.04   //The Period time off the funktion
    private boolean CreatePlant = true   //True = Creating a Plant where the Tendrils are attacked / False = The caster will be the "Plant" and Tendrils are attached to him
    
    //Do not Modificate this unless you understand the code
    private timer      tt          = CreateTimer()  // Do not change this 
    private group      PulledUnits = CreateGroup()  // Do not change this 
    private unit array Plant                        // Do not change this 
    private group      g           = CreateGroup()  // Do not change this
    private boolexpr   filter      = null           // Do not change this
endglobals

//This condition declared if a unit can be Grapped/Targeted by a Tendril
function GrapCondition takes unit a , unit b returns boolean
    return IsPlayerEnemy(GetOwningPlayer(a),GetOwningPlayer(b)) 
endfunction

//This sets how long the Plant lasts 
function PlantDuration takes integer level returns real
    return 8 + 4*(I2R(level))
endfunction

//The Number of Tendrils per level
function TendrilsPerLevel takes integer level returns real
    return I2R(level)
endfunction

//The condition if this script should run
private function RunCondition takes nothing returns boolean
    return  GetSpellAbilityId() == HeroAbility
endfunction

function UnitFilter takes nothing returns boolean
    local boolean ret = false
    if (GetWidgetLife(GetFilterUnit()) > 0.405) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false ) and ( IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) == false ) then
        set ret = ( IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false ) and (IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING) == false ) and (GetUnitFlyHeight(GetFilterUnit()) == 0 )
    endif

    return ret
endfunction

//////////////////////////////////////////////////Main  Struct//////////////////////////////////////////

struct Tendril
    static integer Index = 0
    static Tendril array Data
    boolean base = true
    unit AttachUnit     //The Units this Tendril is attached to
    effect PlantEffect  // The Special effect the Plant got
    effect PlantEffect2 // The Special effect the Plant got
    unit TargetUnit     //The Unit which is currently targeted/pulled by the tendril
    real Distance       //The distance of the Farest point of the Tendril to its attached unit
    real angle          // The angle of the Tendril
    integer Phase       //Defines which movement/Animation is currently done
    // 0 = Birth
    // 1 = Default Position 
    // 2 = Move To Target
    // 3 = Grap Target to Mid 
    // 4 = Return to Default position
    // 5 = death 
    location TendrilLoc
    integer ExecutionsLeft 
    integer rem = 0
    real DefaultMovement = 0      //While being in default position this is a number to make the tendril still move
    unit array TendrilPart[18]    //This is the number of used dummys for the Tendril , MUST be the same number as the TendrilPartsNumber constant
    effect array TendrilModel[18] //This ist each effect attached to the Tendril dummy , MUST be the same number as the TendrilPartsNumber constant
    static method create takes nothing returns Tendril
        local Tendril data = Tendril.allocate()
        set Tendril.Data[Tendril.Index] = data
        set Tendril.Index = Tendril.Index + 1
        return data
    endmethod
endstruct

//////////////////////////////////////////////////Used Functions//////////////////////////////////////////

function GetNearestUnit takes location attach , location loc , location loc2, real radius , unit attachunit returns unit
    local unit ret = null
    local real x1 = GetLocationX(loc)
    local real x2 = 0.00
    local real x3 = GetLocationX(loc2)
    local real y1 = GetLocationY(loc)
    local real y2 = 0.00
    local real y3 = GetLocationY(loc2)
    local unit a = null
    local unit b = null
    local real MinD = radius
    local real D = 0.00
    local real r = 0.00
    call GroupEnumUnitsInRangeOfLoc(g, loc, radius, filter)
    loop
    set a = FirstOfGroup(g)
    exitwhen a==null
    call GroupRemoveUnit(g,a)
        set r = SquareRoot((GetLocationX(attach)-GetUnitX(a))*(GetLocationX(attach)-GetUnitX(a))+(GetLocationY(attach)-GetUnitY(a))*(GetLocationY(attach)-GetUnitY(a)))
        set x2 = GetUnitX(a)
        set y2 = GetUnitY(a)
        set D = SquareRoot((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
        if r >= (TendrilLength * TendrilDefaultPosition) and (D < MinD) and (SquareRoot((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3)) < TendrilLength ) and not(IsUnitInGroup(a,PulledUnits)) and GrapCondition(a,attachunit) == true then
           set MinD = D
           set b = a
        endif
    endloop
    call GroupClear(g)
    set a = null
    return b
endfunction

function GetDistanceCoordinates takes real x , real y , real xx , real yy returns real
    return SquareRoot((x-xx)*(x-xx)+(y-yy)*(y-yy))+0.5
endfunction

function SetUnitZFacing takes unit whichUnit, real facingAngle returns nothing
	local integer i = R2I((facingAngle+OffsetAngle)*0.7+0.5)
	if i>0 then
		call SetUnitAnimationByIndex(whichUnit, i)
	else
		call SetUnitAnimationByIndex(whichUnit, i+252)
	endif
endfunction

function GetUnitZ takes unit u returns real
    local location loc = GetUnitLoc(u)
    local real r = GetLocationZ(loc)
    call RemoveLocation(loc)
    set loc = null
    return r 
endfunction

function Abs takes real a returns real
    local real ret = 0
    if (a >= 0) then
        set ret = a
    else
        set ret = -a
    endif
    return ret
endfunction

function adjust takes real start , real target , real step returns real
    local real ret = 0.00
    if Abs(Abs(target) - Abs(start)) <= step then
        set ret = target
    elseif target > start then
        set ret = start + step
    elseif target < start then
        set ret = start - step
    endif
    return ret
endfunction

function adjustloc takes location loc , location loc2 , real step returns location
    local location ret
    local real x = GetLocationX(loc)
    local real xx = GetLocationX(loc2)
    local real y = GetLocationY(loc)
    local real yy = GetLocationY(loc2)
    local real angle = bj_RADTODEG * Atan2(yy - y, xx - x)
    if SquareRoot((x-xx)*(x-xx)+(y-yy)*(y-yy)) < step then
        set ret = loc2
    else
        set ret =  Location(x + step * Cos(angle * bj_DEGTORAD),y + step * Sin(angle * bj_DEGTORAD))
    endif
    return ret    
endfunction

function GetDistance takes location loc , real x , real y returns real
    return SquareRoot((GetLocationX(loc)-x)*(GetLocationX(loc)-x)+(GetLocationY(loc)-y)*(GetLocationX(loc)-y))+0.5
endfunction

//////////////////////////////////////////////////Callback Function//////////////////////////////////////////

function callback takes nothing returns nothing
    local Tendril data
    local integer run = 1
    local integer i = 0
    local integer ii = 0
    local real x = 0.00 
    local integer a = 1
    local real r = 1
    local real xx = 0.00
    local unit b = null
    local real d = 0.00
    local location loc
    local location loc2 
    loop
        exitwhen i >= Tendril.Index
        set run = 1
        set data = Tendril.Data[i]
            set x = data.Distance
            set data.ExecutionsLeft = data.ExecutionsLeft - 1
            if data.ExecutionsLeft == 0 then
                set data.Phase = 5 
            endif
            if data.Phase == 0 and run == 1 then //Birth - moving to Default position
                set r = PlantHeight + DefaultSinusHeight + TendrilDefaultHeight * (1-TendrilDefaultPosition) * (data.Distance/(TendrilLength*TendrilDefaultPosition))
                set data.Distance = adjust(data.Distance,TendrilLength * TendrilDefaultPosition,BirthAnimationSpeed)
                set a = 1
                loop
                    exitwhen a > TendrilPartsNumber
                    set xx = I2R(a) / I2R(TendrilPartsNumber)
                    call SetUnitFlyHeight( data.TendrilPart[a],  Sin(xx * 3.14159 ) * r  +  (xx * TendrilDefaultHeightGround) + TendrilStartHeight , 0.00 )
                    call SetUnitX(data.TendrilPart[a],GetUnitX(data.AttachUnit) + xx * data.Distance * Cos(data.angle * bj_DEGTORAD))
                    call SetUnitY(data.TendrilPart[a],GetUnitY(data.AttachUnit) + xx * data.Distance * Sin(data.angle * bj_DEGTORAD))
                    call SetUnitZFacing(data.TendrilPart[a],-90+Rad2Deg(Atan(r/(data.Distance)*  3.14159 * Cos( xx * 3.14159 ))))       
                    set a = a + 1
                endloop
                if data.Distance == (TendrilLength * TendrilDefaultPosition) then
                    set data.Phase = 1 // Defaul Position is reached , Tendril is "Activaded" now!
                endif
                set run = 0
            endif
            
            if data.Phase == 1 and run == 1 then //Default Position (moving a bit)
                set r = PlantHeight + DefaultSinusHeight + (TendrilDefaultHeight * (1-(data.Distance/TendrilLength))) 
                set data.DefaultMovement = data.DefaultMovement +DefaultMovementSpeed
                set a = 1
                if data.DefaultMovement > (2*3.14159) then
                   set data.DefaultMovement = data.DefaultMovement - (2*3.14159)
                endif
                loop
                    exitwhen a > TendrilPartsNumber
                    set xx = I2R(a) / I2R(TendrilPartsNumber)
                    call SetUnitFlyHeight( data.TendrilPart[a],  (xx * TendrilTargetHeight) + Sin(xx * 3.14159 ) * (r+(DefaultMovementAmplitude*Sin(data.DefaultMovement-3.14)))  +  (xx * TendrilDefaultHeightGround) + TendrilStartHeight , 500000.00 )
                    call SetUnitX(data.TendrilPart[a],GetUnitX(data.AttachUnit) + xx * (data.Distance+(DefaultMovementAmplitude*Sin(data.DefaultMovement-3.14))) * Cos(data.angle * bj_DEGTORAD))
                    call SetUnitY(data.TendrilPart[a],GetUnitY(data.AttachUnit) + xx * (data.Distance+(DefaultMovementAmplitude*Sin(data.DefaultMovement-3.14))) * Sin(data.angle * bj_DEGTORAD))
                    call SetUnitZFacing(data.TendrilPart[a],-90+Rad2Deg(Atan(r/(data.Distance)*  3.14159 * Cos( xx * 3.14159 ))))       
                    set a = a + 1
                endloop
                set loc = GetUnitLoc(data.AttachUnit)
                set data.TendrilLoc = Location(GetUnitX(data.AttachUnit) + data.Distance * Cos(data.angle * bj_DEGTORAD),GetUnitY(data.AttachUnit) + data.Distance * Sin(data.angle * bj_DEGTORAD))
                set loc2 = GetUnitLoc(data.AttachUnit)
                set b = GetNearestUnit(loc2,data.TendrilLoc,loc,TendrilLength,data.AttachUnit)

                if b != null then
                    set data.TargetUnit = b
                    call GroupAddUnit(PulledUnits,data.TargetUnit)
                    set data.DefaultMovement = 0
                    set data.Phase = 2
                endif
                set b = null
                call RemoveLocation(loc)
                set loc = null
                set run = 0
            endif
            set a = 1
            
            if data.Phase == 2 and run == 1 then //Move to Target
                set loc = GetUnitLoc(data.TargetUnit)
                set data.TendrilLoc = adjustloc(data.TendrilLoc,loc,TendrilSpeed)
                set data.angle = ( bj_RADTODEG * Atan2(GetLocationY(data.TendrilLoc) - GetUnitY(data.AttachUnit), GetLocationX(data.TendrilLoc) - GetUnitX(data.AttachUnit)))
                set data.Distance = SquareRoot((GetLocationX(data.TendrilLoc)-GetUnitX(data.AttachUnit))*(GetLocationX(data.TendrilLoc)-GetUnitX(data.AttachUnit))+(GetLocationY(data.TendrilLoc)-GetUnitY(data.AttachUnit))*(GetLocationY(data.TendrilLoc)-GetUnitY(data.AttachUnit)))
                set d = GetDistanceCoordinates(GetUnitX(data.AttachUnit),GetUnitY(data.AttachUnit),GetUnitX(data.TargetUnit),GetUnitY(data.TargetUnit))
                if d >= TendrilLength + TendrilBendLenght then
                    call GroupRemoveUnit(PulledUnits ,data.TargetUnit)
                    set data.TargetUnit = null
                    set data.Phase = 4
                endif
                if GetLocationX(loc) == GetLocationX(data.TendrilLoc) and GetLocationY(loc) == GetLocationY(data.TendrilLoc) then
                    set data.Phase = 3 
                endif
                set r = PlantHeight + DefaultSinusHeight + TendrilDefaultHeight * (1-(data.Distance/TendrilLength))
                loop
                    exitwhen a > TendrilPartsNumber
                    set xx = I2R(a) / I2R(TendrilPartsNumber)
                    call SetUnitFacing(data.TendrilPart[a],data.angle)
                    call SetUnitFlyHeight( data.TendrilPart[a],  Sin(xx * 3.14159 ) * r  +  (xx * TendrilTargetHeight) + (xx * TendrilDefaultHeightGround * (1-(data.Distance/d))) + TendrilStartHeight , 0.00 )
                    call SetUnitX(data.TendrilPart[a],GetUnitX(data.AttachUnit) + xx * data.Distance * Cos(data.angle * bj_DEGTORAD))
                    call SetUnitY(data.TendrilPart[a],GetUnitY(data.AttachUnit) + xx * data.Distance * Sin(data.angle * bj_DEGTORAD))
                    call SetUnitZFacing(data.TendrilPart[a],-90+Rad2Deg(Atan(r/(data.Distance)*  3.14159 * Cos( xx * 3.14159 ))))   
                    set a = a + 1
                endloop
                set run = 0
            endif
            
            if data.Phase == 3 and run == 1 then //Grap Target to Mid
                set r = PlantHeight + DefaultSinusHeight + TendrilDefaultHeight * (1-(data.Distance/TendrilLength))
                set loc = GetUnitLoc(data.AttachUnit)
                set data.Distance = adjust(data.Distance,PullRange,TendrilSpeed)
                if data.Distance == (PullRange) or (GrapCondition(data.TargetUnit,data.AttachUnit) == false) then
                   set data.Phase = 4
                   call GroupRemoveUnit(PulledUnits ,data.TargetUnit)
                   set data.TargetUnit = null
                endif
                loop
                    exitwhen a > TendrilPartsNumber
                    set xx = I2R(a) / I2R(TendrilPartsNumber)
                    call SetUnitFlyHeight( data.TendrilPart[a],  Sin(xx * 3.14159 ) * r  + (xx * TendrilTargetHeight) + TendrilStartHeight , 0.00 )
                    call SetUnitX(data.TendrilPart[a],GetUnitX(data.AttachUnit) + xx * data.Distance * Cos(data.angle * bj_DEGTORAD))
                    call SetUnitY(data.TendrilPart[a],GetUnitY(data.AttachUnit) + xx * data.Distance * Sin(data.angle * bj_DEGTORAD))
                    call SetUnitZFacing(data.TendrilPart[a],-90+Rad2Deg(Atan(r/(data.Distance)*  3.14159 * Cos( xx * 3.14159 ))))   
                    set a = a + 1
                endloop
                call SetUnitX(data.TargetUnit,GetUnitX(data.TendrilPart[TendrilPartsNumber]))
                call SetUnitY(data.TargetUnit,GetUnitY(data.TendrilPart[TendrilPartsNumber]))
                set run = 0
            endif
            
            if data.Phase == 4 and run == 1 then //Return to the Default Position
                set r = PlantHeight + DefaultSinusHeight + TendrilDefaultHeight * (1-(data.Distance/TendrilLength))
                set data.TendrilLoc = Location(GetUnitX(data.AttachUnit) + data.Distance * Cos(data.angle * bj_DEGTORAD),GetUnitY(data.AttachUnit) + data.Distance * Sin(data.angle * bj_DEGTORAD))
                set d = adjust(GetUnitFlyHeight(data.TendrilPart[TendrilPartsNumber]),TendrilDefaultHeightGround,15)
                set data.Distance = adjust(data.Distance,TendrilLength * TendrilDefaultPosition,TendrilSpeed)
                if data.Distance == (TendrilLength * TendrilDefaultPosition) then
                   set data.Phase = 1
                endif
                loop
                    exitwhen a > TendrilPartsNumber
                    set xx = I2R(a) / I2R(TendrilPartsNumber)
                    call SetUnitFlyHeight( data.TendrilPart[a],  Sin(xx * 3.14159 ) * r  +  (xx * d) + TendrilStartHeight , 0.00 )
                    call SetUnitX(data.TendrilPart[a],GetUnitX(data.AttachUnit) + xx * data.Distance * Cos(data.angle * bj_DEGTORAD))
                    call SetUnitY(data.TendrilPart[a],GetUnitY(data.AttachUnit) + xx * data.Distance * Sin(data.angle * bj_DEGTORAD))
                    call SetUnitZFacing(data.TendrilPart[a],-90+Rad2Deg(Atan(r/(data.Distance)*  3.14159 * Cos( xx * 3.14159 ))))   
                    set a = a + 1
                endloop
                set loc = GetUnitLoc(data.AttachUnit)
                set loc2 = GetUnitLoc(data.AttachUnit)
                set b = GetNearestUnit(loc2,data.TendrilLoc,loc,TendrilLength,data.AttachUnit)
                if b != null then
                    set data.TargetUnit = b
                    call GroupAddUnit(PulledUnits,data.TargetUnit)
                    set data.Phase = 2
                endif
                if b == null then
                endif
                set b = null
                call RemoveLocation(loc)
                set loc = null
                set run = 0
            endif
            
            if data.Phase == 5 then //Death Animation
            
                set data.rem = data.rem + 2
                set xx = I2R(data.rem)/(5*I2R(TendrilPartsNumber))
                call DestroyEffect(data.TendrilModel[data.rem-1])
                call RemoveUnit(data.TendrilPart[data.rem-1])
                call DestroyEffect(data.TendrilModel[data.rem-2])
                call RemoveUnit(data.TendrilPart[data.rem-2])
                set data.TendrilPart[data.rem-2] = null
                set data.TendrilPart[data.rem-1] = null
                set data.Distance = data.Distance - (data.Distance * xx)
                set r = (PlantHeight + DefaultSinusHeight + TendrilDefaultHeight * (1-(data.Distance/TendrilLength)))*(1-I2R(data.rem)/TendrilPartsNumber)
                set data.TendrilLoc = Location(GetUnitX(data.AttachUnit) + data.Distance * Cos(data.angle * bj_DEGTORAD),GetUnitY(data.AttachUnit) + data.Distance * Sin(data.angle * bj_DEGTORAD))
                set d = adjust(GetUnitFlyHeight(data.TendrilPart[TendrilPartsNumber]),TendrilDefaultHeightGround,15)
                set a = data.rem
                if data.rem != TendrilPartsNumber then
                    loop
                        exitwhen a > TendrilPartsNumber 
                        set xx = I2R(a-data.rem) / I2R(TendrilPartsNumber-data.rem)
                        call SetUnitFlyHeight( data.TendrilPart[a],  Sin(xx * 3.14159 ) * r  +  (xx * d) + TendrilStartHeight , 0.00 )
                        call SetUnitX(data.TendrilPart[a],GetUnitX(data.AttachUnit) + xx * data.Distance * Cos(data.angle * bj_DEGTORAD))
                        call SetUnitY(data.TendrilPart[a],GetUnitY(data.AttachUnit) + xx * data.Distance * Sin(data.angle * bj_DEGTORAD))
                        call SetUnitZFacing(data.TendrilPart[a],-90+Rad2Deg(Atan(r/(data.Distance+1)*  3.14159 * Cos( xx * 3.14159 ))))   
                        set a = a + 1
                    endloop
                endif
                
                if data.rem >= TendrilPartsNumber then
                    call DestroyEffect(data.TendrilModel[data.rem])
                    call RemoveUnit(data.TendrilPart[data.rem])
                    set data.TendrilPart[data.rem] = null
                    if data.base == true and CreatePlant == true then
                       call DestroyEffect(AddSpecialEffect(TendrilEffect,GetUnitX(data.AttachUnit),GetUnitY(data.AttachUnit) ))
                       call RemoveUnit(data.AttachUnit)
                    else 
                       call UnitRemoveAbility(data.AttachUnit,PlantSkill)
                       call UnitRemoveAbility(data.AttachUnit,PlantSkill2)
                    endif
                    call DestroyEffect(data.PlantEffect)
                    call DestroyEffect(data.PlantEffect2)
                    call GroupRemoveUnit(PulledUnits,data.TargetUnit)
                    call RemoveLocation(data.TendrilLoc)
                    set data.TendrilLoc = null
                    set data.AttachUnit = null
                    set data.TargetUnit = null
                    set ii = i
                    loop
                        exitwhen ii == Tendril.Index
                        set Tendril.Data[ii] = Tendril.Data[ii+1]
                        set ii = ii + 1
                    endloop
                    set Tendril.Data[Tendril.Index] = 0
                    set i = i -1
                    set Tendril.Index = Tendril.Index - 1
                    call Tendril.destroy(data)
                    else 
                endif                
            endif            
            set i = i + 1
    endloop
    if Tendril.Index > 0 then
        call TimerStart(tt, TimerPeriod, false , function callback)
    else 
    endif
endfunction
    
function ManEatingPlant takes nothing returns nothing
    local integer i = 1
    local integer ii = 0
    local real angle 
    local location loc = GetSpellTargetLoc()
    local real x = 0.00
    local integer a = 1
    local integer level = GetUnitAbilityLevel(GetTriggerUnit(),GetSpellAbilityId())
    local boolean base = true
    local unit Plant = null
    loop 
        exitwhen ii == TendrilsPerLevel(level)

        set angle =  GetRandomReal(0.00,360.00)
        call Tendril.create()
        set Tendril.Data[Tendril.Index-1].angle = angle
        if CreatePlant == true then
            if base == true then
                set Tendril.Data[Tendril.Index-1].AttachUnit = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), DummyID , loc , angle)
                set Plant = Tendril.Data[Tendril.Index-1].AttachUnit
                set Tendril.Data[Tendril.Index-1].PlantEffect = AddSpecialEffectTarget(PlantDummyEffect,Plant,"origin")
                set Tendril.Data[Tendril.Index-1].PlantEffect2 = AddSpecialEffectTarget(PlantDummyEffect2,Plant,"origin")
                call SetUnitScale(Tendril.Data[Tendril.Index-1].AttachUnit,PlantSize,PlantSize,PlantSize)
                call SetUnitFlyHeight(Tendril.Data[Tendril.Index-1].AttachUnit,PlantHeight,500)
                call SetUnitZFacing(Tendril.Data[Tendril.Index-1].AttachUnit,0)
            else 
                set Tendril.Data[Tendril.Index-1].AttachUnit = Plant
                set Tendril.Data[Tendril.Index-1].PlantEffect = AddSpecialEffectTarget(PlantDummyEffect2,Tendril.Data[Tendril.Index-1].AttachUnit,"origin")
                set Tendril.Data[Tendril.Index-1].PlantEffect = AddSpecialEffectTarget(PlantDummyEffect,Tendril.Data[Tendril.Index-1].AttachUnit,"origin")
            endif
        else
            set Tendril.Data[Tendril.Index-1].AttachUnit = GetTriggerUnit()
            if base == true then
                set Tendril.Data[Tendril.Index-1].PlantEffect = AddSpecialEffectTarget(PlantDummyEffect,Plant,"origin")
                set Tendril.Data[Tendril.Index-1].PlantEffect2 = AddSpecialEffectTarget(PlantDummyEffect2,Plant,"origin")
            endif
        endif
        call DestroyEffect(AddSpecialEffect(TendrilEffect,GetUnitX(Tendril.Data[Tendril.Index-1].AttachUnit),GetUnitY(Tendril.Data[Tendril.Index-1].AttachUnit) ))
        call UnitAddAbility( Tendril.Data[Tendril.Index-1].AttachUnit,PlantSkill)
        call SetUnitAbilityLevel(Tendril.Data[Tendril.Index-1].AttachUnit,PlantSkill,level)
        call UnitAddAbility( Tendril.Data[Tendril.Index-1].AttachUnit,PlantSkill2)
        call SetUnitAbilityLevel(Tendril.Data[Tendril.Index-1].AttachUnit,PlantSkill2,level)
        
        set Tendril.Data[Tendril.Index-1].Distance = BirthStartRange
        set Tendril.Data[Tendril.Index-1].base = base
        set Tendril.Data[Tendril.Index-1].Phase = 0 // Birth Animation
        loop
            exitwhen i > TendrilPartsNumber
            set x = I2R(i)/I2R(TendrilPartsNumber)
            set Tendril.Data[Tendril.Index-1].ExecutionsLeft = R2I(PlantDuration(level) / TimerPeriod)
            set Tendril.Data[Tendril.Index-1].TendrilPart[i] = CreateUnit(GetOwningPlayer(GetTriggerUnit()), DummyID , GetUnitX(Tendril.Data[Tendril.Index-1].AttachUnit) + x * Tendril.Data[Tendril.Index-1].Distance * Cos(angle * bj_DEGTORAD),GetUnitY(Tendril.Data[Tendril.Index-1].AttachUnit) + x * Tendril.Data[Tendril.Index-1].Distance * Sin(angle * bj_DEGTORAD) , angle)
            call SetUnitZFacing(Tendril.Data[Tendril.Index-1].TendrilPart[i],-90+Rad2Deg(Atan(TendrilDefaultHeight/(TendrilDefaultPosition*TendrilLength)*  3.14159 * Cos( x * 3.14159 ))))
            set Tendril.Data[Tendril.Index-1].TendrilModel[i] = AddSpecialEffectTarget(TendrilDummyEffect,Tendril.Data[Tendril.Index-1].TendrilPart[i],"origin")
            call SetUnitScale(Tendril.Data[Tendril.Index-1].TendrilPart[i],TendrilSize-(i*TendrilSizeReduction),TendrilSize-(i*TendrilSizeReduction),TendrilSize-(i*TendrilSizeReduction))
            set i = i + 1
        endloop
        set i = 1
        if Tendril.Data[Tendril.Index-1].Index == 1 then
            call TimerStart(tt, TimerPeriod, false , function callback)
        endif
        set base = false
        set ii = ii + 1
    endloop
    
    call RemoveLocation(loc)
    set loc = null
endfunction

//===========================================================================
function Init takes nothing returns nothing
    local trigger tr = CreateTrigger()
    set filter = Filter(function UnitFilter)
    call TriggerRegisterAnyUnitEventBJ(tr, EVENT_PLAYER_UNIT_SPELL_CAST)
    call TriggerAddCondition( tr,Condition(function RunCondition) )
    call TriggerAddAction( tr, function ManEatingPlant )
endfunction

endscope

This Spell uses vJass so it required the Jass New Gen Pack. Get it here.
Thanks to N-a-z-g-u-l for his dummy model

Keywords:
Man, Eating, Plant, Tendril, System, vJass, JonNny, Summon, Grap, Pull
Contents

JonNnys Man Eating Plant (Map)

Reviews
4 November 2015 Bribe: Rejecting due to the status of this resource being "needs fix" for years. 16 Dec 2011 Bribe: The code is really weird with a lot of if/else blocks that do nothing. "adjustloc" leaks a location handle (because it is a local...
Level 11
Joined
Jul 2, 2008
Messages
601
I'm attempting to use it so the caster is a plant, but whenever I import it it doesn't work. Even if I don't make any changes to the trigger besides changing the values of the init, slow, and damage abilities, it doesn't do anything. Any help? ><
Just one dull question, do you have JNPG? :) I mean, does it work at all? Loads in the game?
 
Resubmit it, it will not load until you save again in JNGP.
Else, its pretty good.

EDIT: I tested it, the code is very good, except I hate the usage of massive groups, locations and calculations which slow the pc down alot.



Concept (30):

Idea
10 /10
Complexity
10 /10
Style
10 /10
Comment:
The skill was totally new, very nice concept, very complex, a very nice style. Full score.
Effects (10):

All:
10 /10
Comment:
The 3 effects are very well chosen, not to much, looks really good. Full score, aswell.
Scripting (30):

Speach:
9 /10
Leakage:
7 /10
Effective Coding:
8 /10
Comment:
Coding was good, but it has to much groups, you used Locations, you had alot of calculations which increased the lagg alot. I don't know how to fix the groups, but this spell is to complex to be casted alot of times, try spamming it 10 times, it will blow your pc away.
Score: 64/70
Final Score: 4,57 / 5

Spell is really good. I liked it. [5/5] vote

[X] +Rep
[ ] Report
(Blank box means no action)

 
Last edited:
Level 19
Joined
Feb 4, 2009
Messages
1,313
note: I don't have JNGP

just downloaded it again to see if anything changed

I opened it in WE
pressed start
and instantly saw the WC3 start screen (directly after wc3 startup - NO loading screen)
I closed the map
opened it
started it again
and it started
but on cast nothing happened oO

probably because fo that:
JASS:
function GetDistance takes location loc , real x , real y returns real
    return SquareRoot((GetLocationX(loc)-x)*(GetLocationX(loc)-x)+(GetLocationY(loc)-y)*(GetLocationX(loc)-y))+0.5
    return 0.01
endfunction
wc3 might think that would be return bug and disables it ingame (the spell was not disabeled in the editor)
 
Level 15
Joined
Jan 31, 2007
Messages
502
note: I don't have JNGP

just downloaded it again to see if anything changed

I opened it in WE
pressed start
and instantly saw the WC3 start screen (directly after wc3 startup - NO loading screen)
I closed the map
opened it
started it again
and it started
but on cast nothing happened oO

probably because fo that:
JASS:
function GetDistance takes location loc , real x , real y returns real
    return SquareRoot((GetLocationX(loc)-x)*(GetLocationX(loc)-x)+(GetLocationY(loc)-y)*(GetLocationX(loc)-y))+0.5
    return 0.01
endfunction
wc3 might think that would be return bug and disables it ingame (the spell was not disabeled in the editor)

Strange, after the patch nothing seems to have any logic
but i must hae overseen that , thanks - fixed it

but if i forgot it i wonder why it started working for me after removing every other multiple return function and remaining this one... :eekani:

Resubmit it, it will not load until you save again in JNGP.
Else, its pretty good.

EDIT: I tested it, the code is very good, except I hate the usage of massive groups, locations and calculations which slow the pc down alot.



Concept (30):

Idea
10 /10
Complexity
10 /10
Style
10 /10
Comment:
The skill was totally new, very nice concept, very complex, a very nice style. Full score.
Effects (10):

All:
10 /10
Comment:
The 3 effects are very well chosen, not to much, looks really good. Full score, aswell.
Scripting (30):

Speach:
9 /10
Leakage:
7 /10
Effective Coding:
8 /10
Comment:
Coding was good, but it has to much groups, you used Locations, you had alot of calculations which increased the lagg alot. I don't know how to fix the groups, but this spell is to complex to be casted alot of times, try spamming it 10 times, it will blow your pc away.
Score: 64/70
Final Score: 4,57 / 5

Spell is really good. I liked it. [5/5] vote

[X] +Rep
[ ] Report
(Blank box means no action)


Thanks for your review
yes it draines quite much recourses but i dont know any way ti fix
but due its a temporary spell and normally there are not 10 level 3 spells castet at the same time in the area i think its accectable
but i mean... each dynamic tendril contains 16 Dummies forming it
that are 48 dummies per lvl 3 spell
and 10 spells would be ~500 moving dummies x(
 
Level 15
Joined
Jan 31, 2007
Messages
502
Started as DC? :confused:

Anyway, due its one of my older spells i also thought of checking the whole efficiency again but atm busy
i know there are some locations left (also due GetLocationZ() ) but i guess 1-2 could get removed

Maybe after i got internet at home (28.10 <.<) ill rework some small things to update it then
 
Level 1
Joined
Apr 5, 2010
Messages
1
i copied pasted all the dummy units, spells, buff and code but when i cast spell in my map i see the units getting dragged into the target point and getting entangled and stuff but theres no plant model, like all the tendrils and stuff not appearing
 
Top