-
Notifications
You must be signed in to change notification settings - Fork 97
Added patrols.lua library file #4513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,123 @@ | ||||||||||||||||||||||
| -- patrols.lua | ||||||||||||||||||||||
| -- Contains functions to assign individual heroes or parties to patrol locations | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| local function is_close_enough(creature, target) | ||||||||||||||||||||||
| return creature.pos.stl_y < target.stl_y+2 and | ||||||||||||||||||||||
| creature.pos.stl_y > target.stl_y-2 and | ||||||||||||||||||||||
| creature.pos.stl_x < target.stl_x+2 and | ||||||||||||||||||||||
| creature.pos.stl_x > target.stl_x-2 | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| local function UpdatePatrol(patrol) | ||||||||||||||||||||||
| if patrol.leader == nil then | ||||||||||||||||||||||
| return | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
| if patrol.leader.state ~= "MoveToPosition" and patrol.leader.state ~= "GoodDoingNothing" and patrol.leader.state ~= "CreatureDoingNothing" then | ||||||||||||||||||||||
| return | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| local target = patrol.positions[patrol.next_post] | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if is_close_enough(patrol.leader, target) then | ||||||||||||||||||||||
| patrol.next_post = (patrol.next_post % #patrol.positions) + 1 | ||||||||||||||||||||||
| target = patrol.positions[patrol.next_post] | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
| if (patrol.leader.moveto_pos.stl_x ~= target.stl_x or patrol.leader.moveto_pos.stl_y ~= target.stl_y) then | ||||||||||||||||||||||
| patrol.leader:walk_to(target.stl_x,target.stl_y) | ||||||||||||||||||||||
| patrol.leader.state = "MoveToPosition" | ||||||||||||||||||||||
| patrol.leader.continue_state = "GoodDoingNothing" | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| function UpdatePatrols() | ||||||||||||||||||||||
| for _, patrol in ipairs(Game.patrols) do | ||||||||||||||||||||||
| UpdatePatrol(patrol) | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| local function InitializePatrols() | ||||||||||||||||||||||
| RegisterTimerEvent(UpdatePatrols, 17, true) | ||||||||||||||||||||||
| Game.patrols = {} | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| function LeaderDeath(eventData,triggerData) | ||||||||||||||||||||||
| local patrol = Game.patrols[triggerData.patrol_idx] | ||||||||||||||||||||||
| if patrol == nil then | ||||||||||||||||||||||
| return | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if patrol.partybackup then | ||||||||||||||||||||||
| patrol.leader = patrol.partybackup.party[1] | ||||||||||||||||||||||
| if patrol.leader == nil then | ||||||||||||||||||||||
| patrol.leader = patrol.partybackup | ||||||||||||||||||||||
| end | ||||||||||||||||||||||
|
||||||||||||||||||||||
| end | |
| end | |
| -- Remove old leader death trigger before registering a new one | |
| RemoveTrigger(triggerData.trigger) |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The succession logic is confusing. According to Creature.lua line 9, party[1] is always the leader of the party. So patrol.partybackup.party[1] would be partybackup itself if partybackup is a party leader. The condition at line 53 will always be false if partybackup has a party (since party[1] == partybackup), making this check unnecessary. The intent appears to be to promote partybackup to the new leader, which should be done directly without the intermediate check.
| patrol.leader = patrol.partybackup.party[1] | |
| if patrol.leader == nil then | |
| patrol.leader = patrol.partybackup | |
| end | |
| -- Promote the backup unit directly to be the new leader | |
| patrol.leader = patrol.partybackup |
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential nil access when checking patrol.leader.party. If patrol.leader exists but doesn't have a party field (or party is nil), accessing party[2] will cause an error. Although Creature.lua defines party as a field, it may not always be initialized for all creatures. Consider adding a check to ensure party exists before accessing party[2].
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code attempts to remove the trigger using triggerData.trigger, but triggerData.trigger is never set anywhere in this file. The trigger system doesn't automatically populate triggerData with a reference to the trigger object. This means RemoveTrigger is being called with nil, which will fail to remove the trigger and cause a memory leak. The trigger reference needs to be stored in triggerData when it's created, or the trigger should be removed using a different mechanism.
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the leader dies and there is no backup, the old trigger for the dead leader is removed but the patrol remains in the Game.patrols table. The UpdatePatrol function will continue to be called for this patrol, but will do nothing since patrol.leader is nil. However, the patrol entry remains in memory indefinitely. Consider removing the patrol from the Game.patrols table when there are no more creatures to continue it, to prevent accumulation of dead patrol entries.
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential nil access when checking patrol.leader.party. If patrol.leader exists but doesn't have a party field (or party is nil), accessing party[2] will cause an error. Although Creature.lua defines party as a field, it may not always be initialized for all creatures. Consider adding a check to ensure party exists before accessing party[2].
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the old backup creature dies and a new backup is assigned from the leader's party, the old trigger for the deceased backup is not removed. This will cause the BackupDeath trigger to remain in the Game.triggers table even though the creature is dead, leading to a memory leak of unused triggers. The trigger should be removed before registering a new one, similar to how it's handled in the LeaderDeath function at line 69.
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BackupDeath trigger is never removed when the backup dies. Unlike LeaderDeath which removes the trigger at line 69 when there's no backup left, BackupDeath doesn't clean up its own trigger. This means when a backup creature dies, their death trigger remains in the Game.triggers table indefinitely, causing a memory leak. The trigger should be removed using RemoveTrigger(triggerData.trigger) before potentially registering a new one or when setting partybackup to nil.
Copilot
AI
Jan 28, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential nil access when checking leader.party. If leader doesn't have a party field (or party is nil), accessing party[2] will cause an error. Although Creature.lua defines party as a field, it may not always be initialized for all creatures. Consider adding a check to ensure party exists before accessing party[2].
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential nil access error. If the creature has not been given any movement orders yet, moveto_pos might be nil or uninitialized, causing this line to error when accessing moveto_pos.stl_x or moveto_pos.stl_y. Consider adding a nil check or initializing moveto_pos to a safe default value when first creating the patrol.