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

Moderator

M

Moderator

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 location that you return, it doesn't recycle the handle ID).

According to one of our Hive members it also doesn't work with multi-cast but I have not confirmed this.

You shouldn't be using locations anywhere here, anyway.

The code is some of the most unreadable I've ever seen. You should store big, repeat-reference things which hinder readability into locals so that your code makes more sense.
 

Rmx

Rmx

Level 19
Joined
Aug 27, 2007
Messages
1,164
Review

Idea/Creativity : 9.5/10
Trigering/Scripting : 9.5/10 ( i know vJASS lool )
Balance/in game play : 8.5/10
Description/Originality : 6/10
Efficiency : 9/10
User Friendly : 10/10

Is Multi Instanceable : [OFC]

Final Rating : 52.5
Status : Highly Recommended

Rating System
0 - 15 = SHIT
16 - 25 = Unacceptable
26 - 35 = Lacking
36 - 45 = Useful
46 - 55 = Recommended - Highly Recommended
56 - 60 = EPIC *Highly Recommended *


My View of the spell.
Great Spell can be Done in various ways but do a better description can u ...
U could get an EPIC score.........


~~RMX~~
 
Level 8
Joined
Dec 16, 2007
Messages
252
I really love this spell.

By the way, are you able to configure the spell when a unit is being grabbed by the plant again?

For example if a footman is being grabbed by the plant, I want it to take 5 seconds before this unit can be grabbed again.

If it would be too much trouble forget it.


Edit: Also, when I tried to import the spell to my map, the tendrils had about 0 height (all of them) and dissapeared after 4 seconds. I tried to fix the GetUnitZ function since I had one with the same name and changed it to GetUnitZZ, still didn't work, changed it back to GetUnitZ and disabled my other trigger that used the same name, still the same.
 
Last edited:
Level 25
Joined
Jun 5, 2008
Messages
2,572
Really nice 5/5 for the spell^^

Now the thing that interests me is the dummy unit's Z facing, how many angles can the dummy model support?
All 360 or?
I also want to know when refering to facingAngle is that unit facing angle(SetUnitZFacing function) or some custom one?
I may snatch the dummy model from the map for my needs.

[offtopic]
Strange how there aren't any spells in the directors cut, isn't it?
 
Level 15
Joined
Jan 31, 2007
Messages
502
PS. Are you swedish? Seems like it, looking at the Hero name:p

Nope, Im german :) Hmm.. strange name the editor gave this hero

I really love this spell.

By the way, are you able to configure the spell when a unit is being grabbed by the plant again?

For example if a footman is being grabbed by the plant, I want it to take 5 seconds before this unit can be grabbed again.

If it would be too much trouble forget it.


Edit: Also, when I tried to import the spell to my map, the tendrils had about 0 height (all of them) and dissapeared after 4 seconds. I tried to fix the GetUnitZ function since I had one with the same name and changed it to GetUnitZZ, still didn't work, changed it back to GetUnitZ and disabled my other trigger that used the same name, still the same.

Yes i could make that delayed, this would not be hard
i just goota add a delayed Removal from the "PulledUnits" group

Are you sure your dummy has "flying" as the movement type ? Ive got no idea why the tendrils should disappear faster Oo
else if you got problems send me your map i can take a look at it

Because its scoped the function should not double because everything gets a "Plant" Prefix

Really nice 5/5 for the spell^^

Now the thing that interests me is the dummy unit's Z facing, how many angles can the dummy model support?
All 360 or?
I also want to know when refering to facingAngle is that unit facing angle(SetUnitZFacing function) or some custom one?
I may snatch the dummy model from the map for my needs.

[offtopic]
Strange how there aren't any spells in the directors cut, isn't it?

The model has 270 different animations for the Z Facing but because there are not 1° steps it supports all degrees
This function you mentioned stets the dummys Angle, thats true
If you use it please credit N-a-z-g-u-l because he made that model
i guess Vexorian used such a model the first time in his caster system

How should i change the effects and the dummys i tried in the normal WE ... but they gave like 214235 errors :p ........ anyway i think it should work in JNPG will it work there ???
Yes , It uses vJass so you need the Jass New Gen Pack

where can i get JNGP?
You can get it on www.wc3c.com , or click this virus
 
Level 10
Joined
Sep 6, 2008
Messages
423
Finaly released! :D When I first saw you uploading WIP's of it (can't remember how long ago) I got amazed but now when I tried it ingame I'm speechless, this is so epic that it can't even be described with words :D 5/5 from me and have a cookie :cute:
 
Level 5
Joined
Jul 6, 2008
Messages
65
i...i...i dont know what to say...is there any words to describe this ?
could sommone bring me a dictionary from the future ? i need a word for..epic..godly..extreme...unimagenable together is that possible...

i know!!!!

EXTREMLY GODLIKE BEYOND OUR IMAGINATION!!!!! EPIC JOHNNY ^^
 
Level 15
Joined
Jan 31, 2007
Messages
502
I also had some bugs when uploading it

most times i get an 417 exceptation failed message when submissing anything
then after trying again it works. This time it was strange
it told me the spell would exist but it did not really, was not in spell database and now shown as an Resource of mine
but it was linked in the error message so i deleted it but it was still kinda there and disabled uploading it till i saved it with the WE again and renamed it
 
Level 15
Joined
Jan 31, 2007
Messages
502
I tried to edit with jpgn and it had a million errors ane it would work
thx 4 sending me

I did not get million bugs but i also got some
this is no bug of this spell, but a strange wc3 peculiarity
It has to do with the Model strings in GUI and Jass. they are not the same because in GUI they got "\" between each keywordk and in Jass they got "\\"

so due you copied the string out of an GUI trigger i guess it buggs.

change the string to added form "Doodads\Ruins\Plants\Ruins_Flower\Ruins_Flower1.mdl" to "Doodads\\Ruins\\Plants\\Ruins_Flower\\Ruins_Flower1.mdl" and it works :)
 
Level 7
Joined
Jan 15, 2008
Messages
179
thx 4 sending me

I did not get million bugs but i also got some
this is no bug of this spell, but a strange <acronym title="Warcraft 3">wc3</acronym> peculiarity
It has to do with the Model strings in GUI and Jass. they are not the same because in GUI they got "\" between each keywordk and in Jass they got "\\"

so due you copied the string out of an GUI trigger i guess it buggs.

change the string to added form "Doodads\Ruins\Plants\Ruins_Flower\Ruins_Flower1.mdl" to "Doodads\\Ruins\\Plants\\Ruins_Flower\\Ruins_Flower1.mdl" and it works :)


Thanks I knew that you need 2 X / but i overlooked that thanks.
 
Level 15
Joined
Jul 19, 2007
Messages
618
very creative idea in my option. spell looks cool and nice use of dummy (angle). what is most impressive is that you as well made spell more editable then your older ones. code as well looks a little more readable. i can see you are still not using array extended structs but thats your decision, i just thought that it would not just be a little faster (i dont care about this so much) i thought it would be easier for you to code your spell...

anyway this is nice job i am sure this can be usefull in many wc modes...

Leakless: as fare as i can see it is.

MUI: as well, can be cast by any amount of units at same time.

Bug free: we can never know (well you found my hard bug) but seems i cant find any bug in your spell, so sry and gj

Idea: Very nice idea its different from others especially that dummy z angle (well done)

Editable: Seems editable enough, which means new spell from this one can be dones quickly...

Usefull: I think it can be quite usefull for wc maps / mods...


Overall in my option its a nice spell and i like it +rep for that hard work!
Greets!
~Dark Dragon
 
Level 8
Joined
Dec 22, 2008
Messages
207
Help? / Help!

ERROR!
Hey erm, I don't know if other people have this... but as soon as I change something in the script and try to test that (seriously anything.. I pressed space and then backspace and tested), it just won't start up the map and it comes up with this: (430 compile errors). :sad:
 

Attachments

  • Error!.JPG
    Error!.JPG
    48.5 KB · Views: 152
Level 8
Joined
Dec 22, 2008
Messages
207
Oops :p Lawl
aite... okay... thanks;) Great, awesome most epic spell ever.
------------------------------------------------See dat? ^
That's a full stop. No one's gnna argue and tell anyone this spell sucks.
+ rep

EDIT:
What's JNGP?? I'm sorry and I'm probably appearing really newbish... But can you explain what it is? Where I can download the program?
Or if it has anything to do with WE NewGen (or summin like dat).
 
Last edited:
Level 15
Joined
Jan 31, 2007
Messages
502
I think this is some sort of mistake in ur code ?? ...... why is there 18 not 16 ?
dunno , i can remember that it bugged with 16 or sth , forgot to test or change it but it works now >.<

Jass NewGen Pack = JNGP

I don't have a download link unfourtunately.

Y, it requires JPGN
due some people didnt know that and i frgot to mention i added a link and hint in the description to dl JNPG
 
Level 15
Joined
Jan 31, 2007
Messages
502
Doubleclicking a map will open it in the normal WE, Open JNGP and then browse for the map
Before testing you have to save the map.
If you did that i dont know why it should not work

... and if you got problems it would always be helpful if you could tell us WHICH errors appear, "the same errors" is not that helpful
 
Level 3
Joined
Feb 24, 2009
Messages
42
Looks awesome but I'm having some problems.

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? ><
 
Top