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

First Time With LUA. Need Help On Projectiles

Status
Not open for further replies.
Level 11
Joined
Aug 6, 2009
Messages
697
I'm trying to learn how to create pseudo objects with LUA and I managed to create a bullet, a node, and a linked list. I think they should be functioning normally.


The below is the code for the bullet which I think is working fine.
JASS:
function newBullet(x,y,z,time,angle,distance,unit,dummy,player, damage)
    return 
    {
        x = x or 0,
        y = y or 0,
        z = z or 0,
        time = time or 0,
        angle = angle or 0,
        distance = distance or 0,
        unit = unit or 0,
        dummy = dummy or 0,
        player = player or 0,
        speed = ((distance/time) * 0.03),
        damage = damage or 0,
       
        Move = function(self)
            --DisplayTextToForce(GetPlayersAll(), "0")
            local x = 0
            local y = 0
            --DisplayTextToForce(GetPlayersAll(), "1")
            y = self.y
            x = self.x
            --DisplayTextToForce(GetPlayersAll(), "2")
            x = x + (self.speed * Cos(self.angle))
            y = y + (self.speed * Sin(self.angle))
            --DisplayTextToForce(GetPlayersAll(), "3")
            if(CheckMapBounds(x, y)) then
                self.y = y
                self.x = x
                --DisplayTextToForce(GetPlayersAll(), "4")
                SetUnitX(self.dummy, x)
                SetUnitY(self.dummy, y)
            end
            --DisplayTextToForce(GetPlayersAll(), "5")

       
        end,
        Destroy = function(self)
            --self.x = nil
            --self.y = nil
            --self.z = nil
            --self.time = nil
            --self.angle = nil
            --self.distance = nil
            --self.unit = nil
            RemoveUnit(self.dummy)
            --self.dummy = nil
            --self.player = nil
            --self.speed = nil
            --self.damage = nil
        end
    }
end


Below is the code for a Node and Linked List.
JASS:
function newNode(data)

return
{
    data = data or 0,
    next = nil
}

end

function newLinkedList()

return
{
    header = nil,
    current = header,
    previous = nil,
    length = 0,

    Start = function(self)
    --DisplayTextToForce(GetPlayersAll(), "0")
        self.current = self.header
        self.previous = nil
    end,
   
    isEnd = function(self)
        --DisplayTextToForce(GetPlayersAll(), "1")
        if (self.current.next == nil) then
            --DisplayTextToForce(GetPlayersAll(), "11")
            return true
        end
        --DisplayTextToForce(GetPlayersAll(), "12")
        return false
    end,

    Next = function(self)
        --DisplayTextToForce(GetPlayersAll(), "2")
        if (self:isEnd() == false) then
            self.previous = self.current
            self.current = self.current.next
        end
    end,

    getData = function(self)
        --DisplayTextToForce(GetPlayersAll(), "3")
        return self.current.data
    end,
   
    addNode = function(self, data)
        --DisplayTextToForce(GetPlayersAll(), "4")
        if(self.header == nil) then
            self.header = newNode(data)
            self.current = self.header
            self.previous = nil
            self.length = self.length + 1
        else
            self.previous = self.current
            self.current = newNode(data)
            self.current.next = self.previous.next
            self.previous.next = self.current
            self.length = self.length + 1
        end
    end,

    removeCurrentNode = function(self)
        if(self.header == self.current) then
            self.header = self.current.next
            self.current.data = nil
            self.current.next = nil
            self.current = self.header
            self.previous = nil
        else
            self.current = self.current.next
            self.previous.next = self.current
        end
        self.length = self.length - 1
    end
}

end

  • LinkedListCreate
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Custom script: BulletList = newLinkedList()


I create bullets in one trigger and add them to the linked list:
  • CreateBullet
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Set TempInt = (Player number of Player 1 (Red))
      • Custom script: MoveLocation(udg_Point, GetWidgetX(udg_PlayerHero[udg_TempInt]), GetWidgetY(udg_PlayerHero[udg_TempInt]))
      • Custom script: MoveLocation(udg_Point2, GetWidgetX(udg_sysMovement_DummyTarget[udg_TempInt]), GetWidgetY(udg_sysMovement_DummyTarget[udg_TempInt]))
      • Set TempReal = (Angle from Point to Point2)
      • Custom script: udg_TempReal2 = Deg2Rad(udg_TempReal)
      • Custom script: Bullet2 = newBullet(GetWidgetX(udg_PlayerHero[udg_TempInt]), GetWidgetY(udg_PlayerHero[udg_TempInt]), 50, 0.5, udg_TempReal2, 2000, 0, 0, 1, 3)
      • Custom script: udg_TempInt = Bullet2.player
      • Custom script: MoveLocation(udg_Point, Bullet2.x, Bullet2.y)
      • Unit - Create 1 Bullet for (Player(TempInt)) at Point facing TempReal degrees
      • Custom script: Bullet2.dummy = GetLastCreatedUnit()
      • Custom script: BulletList:addNode(Bullet2)

Linked List Test is where the problem lies.
  • LinkedListTest
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Custom script: local i = 0
      • Custom script: BulletList:Start()
      • Custom script: while (true) do
      • Custom script: if (i == BulletList.length) then break end
      • Custom script: if BulletList:getData().time > 0 then
      • Custom script: BulletList:getData():Move()
      • Custom script: BulletList:getData().time = BulletList:getData().time - 0.03
      • Custom script: MoveLocation(udg_Point, BulletList:getData().x, BulletList:getData().y)
      • Cinematic - Ping minimap for (All players) at Point for 1.00 seconds
      • Custom script: bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 75.00 of Point) and do (Actions)
        • Loop - Actions
          • Custom script: if IsUnitEnemy(GetEnumUnit(), GetOwningPlayer(BulletList:getData().dummy)) and (GetUnitState(BulletList:getData().dummy, UNIT_STATE_LIFE) > 0) then
          • Game - Display to (All players) the text: 1
          • Custom script: udg_TempInt = GetPlayerId(GetOwningPlayer(BulletList:getData().dummy))
          • Custom script: udg_TempReal = BulletList:getData().damage
          • Unit - Cause PlayerHero[1] to damage (Picked unit), dealing 1.00 damage of attack type Normal and damage type Normal
          • Game - Display to (All players) the text: 2
          • Custom script: end
      • Custom script: else
      • Custom script: BulletList:getData():Destroy()
      • Custom script: BulletList:removeCurrentNode()
      • Custom script: end
      • Custom script: BulletList:Next()
      • Custom script: i = i + 1
      • Custom script: end

The above code in "LinkedListTest" as shown works correctly.
However if I throw in
  • Custom script: BulletList:getData().time = 0
here
  • Unit Group - Pick every unit in (Units within 75.00 of Point) and do (Actions)
    • Loop - Actions
      • Custom script: if IsUnitEnemy(GetEnumUnit(), GetOwningPlayer(BulletList:getData().dummy)) and (GetUnitState(BulletList:getData().dummy, UNIT_STATE_LIFE) > 0) then
      • Game - Display to (All players) the text: 1
      • Custom script: udg_TempInt = GetPlayerId(GetOwningPlayer(BulletList:getData().dummy))
      • Custom script: udg_TempReal = BulletList:getData().damage
      • Unit - Cause PlayerHero[1] to damage (Picked unit), dealing 1.00 damage of attack type Normal and damage type Normal
      • Game - Display to (All players) the text: 2
      • Custom script: BulletList:getData().time = 0
      • Custom script: end
it causes the entire system to screw up by not even moving the majority of the projectiles. I don't know why that line screws up the system when I already modify the time value. Then, when the time value becomes 0 I destroy and remove the current node from the list. It's almost like it's a graphical thing because even when the projectiles are no longer moved or removed the points are still shifted and damage is done in a line despite the absence of projectiles(I used coordinates saved in the object so it's independent of the dummy unit's position). I've been stuck on this for 6 hours and can't find an answer.

I've attached the map in question and put the 5 problem children under the "WhereTheProblemLies" folder. If you can help me and give me tips on LUA that would be appreciated. To simulate the problem, walk using the arrow keys and mouse towards the blue rifleman.

Also as a side question, how can I properly delete a created object? Do I just get rid of any reference to it like I'm doing and it will just get automatically freed in a garbage collector?
 

Attachments

  • QuickGunProject32.w3x
    82.2 KB · Views: 25
I would advise using print(a, b, "Test") to Display Messages or just print("Test"). Print can Display multipe Arguments and displays any type without any modification cause it evokes tostring for non strings (might look wierd although sometimes).

one can surrond ones executive Code with xpcall to get some error Messages. Although the given error lines are from the war3map.lua file most times, therefore it is required to extract the script file to understand it.
Lua:
function err(x)
    print(x)
    return x
end

function myFunction()
 xpcall(function()
  ….
  ….
 end, err)

end
 
Status
Not open for further replies.
Top