Requires KitanoiFuncs(Free)
Requires Argus(Paid) by Rikudou http://wiki.mmominion.com/doku.php?id=Argus
Requires TensorCore(Free) by Rikudou http://wiki.mmominion.com/doku.php?id=TensorCore
All duty support dungeons are supported upto The Lunar Subterrane.
There are combat routines built into KDF for all jobs except:
KDF fully integrates with Latty's MSQ profiles and can take control to complete the dungeons using Duty Support. Any duty that was added to the Duty Support system after patch 6.3 requires the KDF Quest Expansion 1 to be automatically completed while questing.
There are a number of solo MSQ duties that are also included that are not automatically completed by the quest profiles.
This combination can run 1-90 uninterrupted barring any 8 person trial, and the required role quest in Shadowbringers.
With the KDF Quest Expansion 1, quest integration is expanded to Sebbs' class quests. MSQ+Class Quests cannot be run together.
Undersized : Unrestricted Party : 解除限制 : 制限解除
Synced : Regular Duty : 通常任务 : 通常コンテンツ
Trust : 亲信战友
Squadron : 冒险者分队 : 冒険者小隊
Built In : 内建
No Duty Finder Support - Ever.
Requires 4 botted accounts for synced 4 man dungeons.
Requires 8 botted accounts for synced 8 man dungeons.
Requires at least 1 botted account for unsynced dungeons.
Requires 1 botted account for story mode solo dungeons - trust dungeons - squadrons
FPS - each instance should be 25 fps minimum. Some fights will cause the fps to drop calculating safe spots and 25fps is sufficient even with the drop.
Lower fps you will have issues.
Example Profile:
local tbl = { name = "Stone Vigil synced no loot", dutyid = 168, objectivedestinations = { [1] = {objective = 1, pos = {x = 0.58, y = 0.09, z = 112.31}}, [2] = {objective = 2, pos = {x = 49.50, y = 4, z = -79.79}}, [3] = {objective = 3, pos = {x = -0.00, y = 0.01, z = -265.70}}, }, forcemeleerange = {1677}, queuetype = 1, interactdistance = 20, enemytargetdistance = 15, tankat = { [1] = {contentid = 1677, frompercent = 100, topercent = 95, pos = {x = 0.05, y = 0.01, z = 107.83}, desc = "tank first boss away from party from 100-95%"}, }, hasbuff = { }, interacts = { [1] = {contentid = 2001880, priority = 1, req = {objective = 3, complete = false}, priority = 1, type = "strongroom gate"}, }, avoidentity= { [1] = {contentid= 1678, radius = 6}, }, incombatinteract= { [1] = {interactid= "2001884;2001885;2001886", req = {castingid = 1028, desc = "isegbind casting"}, type= "interact", who = "closest", desc = "berthas"}, }, prioritytarget = { }, puddledata= { [1] = {castid = 1023, radius= 5, duration = 60, desc = "ice puddle left by isebind"}, [2] = {castid = 1024, radius= 6, duration = 60, desc = "ice puddle left by isebind while flying"}, }, advancedavoid = { }, overheadmarkers = { }, } return tbl
dutyid - [int][required] This is the localmapid of the dungeon you wish to run.
dutyid = 616,
d(Player.localmapid)
mesh - [string][optional] The name of the mesh you want to use, or blank.
name = "Shisui of the Violet Tides",
objectivedestinations - [table][required] - The positions of each objective. If the dungeon is linear, you can define each objective as the same position. Ensure there is an entry for the correct amount of objectives in the dungeon.
objectivedestinations = { [1] = {objective = 1, pos = {x = 21.91, y = 7.10, z = 27.38}}, [2] = {objective = 2, pos = {x = 114.30, y = -3.155, z = -24.09}}, [3] = {objective = 3, pos = {x = -13.54, y = 5.74, z = -91.40}}, [4] = {objective = 4, pos = {x = -113.26, y = -1.069, z = -53.45}}, [5] = {objective = 5, pos = {x= -13.3, y= 35.67, z= -237.70}}, },
queuetype - [int][required] - 1: synced, 2: unsynced, 3: trusts, 4: squadron, 10: variant, 13: criterion
queuetype = 2,
type - [string][required*] * regular duty doesn't require, trust or story does require. options: “story”, “trust”, “duty”, “vc”
type = "story",
vcactions [table][optional] - used to determine which variant dungeon actions to queue with. If nil, cure and rampart are selected.
vcactions = {0,4},
[0] = "Variant Cure", [1] = "Variant Ultimatum", [2] = "Variant Raise", [3] = "Variant Spirit Dart", [4] = "Variant Rampart",
trustdata [table][required*] * required if using type = “trust”, else it isn't required.
trustdata = { mapid = 837, scenario = false, },
bossids - [table][optional] - Expects contentid. Will force melee range above 90% HP on those targets.
bossids = {6241,6237},
interacts - [table][required] - Field is required even if it is just an empty table.
interacts = { [1] = {contentid = 897, priority = 2, type = "loot"}, [2] = {contentid = 893, priority = 2, type = "loot"}, [3] = {contentid = 894, priority = 1, type = "loot"}, [4] = {contentid = 898, priority = 1, type = "loot"}, [5] = {contentid = 895, priority = 2, type = "loot"}, [6] = {contentid = 896, priority = 3, type = "loot"}, [7] = {contentid = 899, priority = 4, type = "loot"}, [8] = {contentid = 1004346, priority = 1, req = {objective = 1, complete = false}, type = "brayflox longstop - get first key"}, [9] = {contentid = 2001537, priority = 9, desc = "Powder Chamber", req = {objective = 1, value = 2}}, [10] = {contentid = 2000180, priority = 10, desc = "Blasting Device", req = {type = "noenemy"}}, [11] = {contentid = 1013331, priority = 11, req = {objective = 1, name = "???"}, type = "get keys"}, },
Options:
prioritytarget - [table][req]
prioritytarget = { [1] = {contentid = 6238, priority = 1, type = "first boss scorpion"}, [2] = {contentid = 6244, priority = 2, type = "last boss sharks"}, [3] = {contentid = 6245, priority = 3, type = "something"}, },
Table can be empty, but is a required to be in the profile.
hasbuff - [table][optional] - Handles specific mechanics when a buff is detected on the player. Two modes available.
hasbuff = { [1] = {type = "move", buffid = 123, pos = {x=2,y=1,z=2}} [2] = {type = "interact" interactid = 123456, stacksrequired = 2} },
advancedavoid - [table][optional]
advancedavoid = { [1] = {castingid = 545454, type = "los", args = {entityone = 8787887, entitytwo = 78787878, dist = 10}}, [2] = {castingid = 998899, type = "singlefixed", pos = {[1] = {x=1,y=2,z=3}}}, [3] = {castingid = 12587, type = "faceaway"}, [4] = {castingid = 8058, type = "multifixed", pos = {[1] = {x=-9.98,y=27.4,z=-198.46},[2] = {x=-10.02,y=27.4,z=-218.2},[3] = {x=9.93,y=27.4,z=-218.25},[4] = {x=10.04,y=27.4,z=-198.2}}}, [5] = {castingid = 5557, type = "moveinfront"}, [6] = {castingid = 5557, type = "movebehind"}, [7] = {castingid = 20999, type = "movetoentity", entitylist = "contentid=9511,maxdistance30", targetable = false, desc = "last boss blue pool"}, [8] = {castingid = 16777, type = "setdistance", dist = 2, desc = "pendulum"}, [9] = {type = "trust", castingid = 74584}, [10] = {type = "trust", trusttype = {entity = 1234, pos = {x = 1, y = 2, z = 3}, variance = 5}}, [11] = {type = "custom", customdetails = "function", functionname = "customfunction", functioncode = "function customfunction() Player:MoveTo(347,43,-220) d('1') end"}, [12] = {type = "custom", customdetails = "libraryfunction", functioncode = "KitanoiFuncs.customfunction()"}, [13] = {castingid = 16777, type = "setdistancefrom", pos = {x=0,y=1,z=3}, dist = 2, desc = "pendulum"}, },
Custom Functions Timers:
KitanoiSettings.DFTimer KitanoiSettings.DFTimer2 KitanoiSettings.DFTimer3 KitanoiSettings.DFTimer4 KitanoiSettings.DFTimer5
These are ints. They are used as so:
--3000 can be changed to as often as you want it to run if (TimeSince(KitanoiSettings.DFTimer)>3000 or KitanoiSettings.DFTimer == 0) then --do something --set the timer as now so to delay again. KitanoiSettings.DFTimer = Now() end
These two options are in advancedavoid, but will be called constanly so don't only need to be used for avoidance tasks. Ensure in your function if you call Player:Move(x,y,z) to add a line KitanoiSettings.avoidingtime = Now(). This is to ensure your movement code will work and my addon doesn't try to take over.
Using these options, you will move to the point specified around your targeted enemy. Useful for spinning attacks.
overheadmarkers - [table][optional] Will be able to specify markers and types and whether to stack or spread.
overheadmarkers = { [1] = {id = 123, contentid = "6237", desc= "spread", type = "move", detectwho = "me", pos = {[1] = {x=-9.98,y=27.4,z=-198.46},[2] = {x=-10.02,y=27.4,z=-218.2},[3] = {x=9.93,y=27.4,z=-218.25},[4] = {x=10.04,y=27.4,z=-198.2}}, returnpos = {[1] = {x=-1.98,y=27.4,z=-118.46},[2] = {x=-1.02,y=27.4,z=-208.2},[3] = {x=3.93,y=27.4,z=-248.25},[4] = {x=7.04,y=27.4,z=-178.2}}, timetoreturn = 5}, [2] = {id = 124, contentid = "6237", desc= "stack", type = "move", detectwho = "any", pos = {[1] = {x=-9.98,y=27.4,z=-198.46},[2] = {x=-9.98,y=27.4,z=-198.46},[3] = {x=-9.98,y=27.4,z=-198.46},[4] = {x=-9.98,y=27.4,z=-198.46}}, --all move to same point to stack timetoreturn = 5}, }, --movetoentity overheadmarker [3] = {id = 62, contentid = "9264", desc= "lastboss stacking", type = "move", detectwho = "any", movetoentity = true, timetoreturn = 5, }, [4] = { id = 62, contentid = "9263", desc= "secondboss stacking", precise = false, type = "move", detectwho = "any", pos = { [1] = {x=20,y=110,z=-75,}, [2] = {x=20,y=110,z=-75,}, [3] = {x=20,y=110,z=-75,}, [4] = {x=20,y=110,z=-75,}, }, timetoreturn = 4, }, }, },
useactions [table][optional] Will attempt to use duty actions. Options for target are “target” and “me” and enemypos (like cannons)
useaction = { [1] = {actiontree = 1, actionid = 9823, target = "target", contentid = 6909, desc = "shatterstone"}, [2] = {actiontree = 1, actionid = 9824, target = "target", contentid = 6909, desc = "shatterstone"}, [3] = {actiontree = 1, actionid = 12257, target = "enemypos", contentid = 297, desc = "cannon in castrum meridianum"}, },
Can use the following in the console to find actions:
KitanoiFuncs.FindAction(str)
Replace str with the action name inside of “ - case doesn't matter
enemytargetdistance [int][optional] set this to the distance you wish the radius around the tank (or solo) character to be checked when trying to target enemies. If you are finding a nav issue whereas your character runs passed a boss, increase this number until you stop running past. If this option isn't used, the default distance is 30.
enemytargetdistance = 30,
dontclearfriendlytargets [table][optional]
dontclearfriendlytargets = {1234,4567,8901}
By default, Dungeon Framework clears target whenever you are targeting a friendly entity. When using UseAction, you may need to be targeting the cannon or object. Put that object contentid in this table and it will not clear the target automatically.
Free For All[bool][optional] Profile level setting Free For All option.
FFA = true,
prioritytargetdistance [int][optional] distance to search for priority targets. If this option isn't used, the default distance is 30.
prioritytargetdistance = 30,
interactdistance [int][optional] distance to search for interacts (loot,keys,doors). This only works for out of combat interacts. In combat interacts like those used with hasbuff has a distance of 50 regardless. If this option isn't used, the default distance is 30.
interactdistance = 30,
requeuetimer [int][optional] Time required after leaving a dungeon before requeuing. If this option isn't used, the default time is 15 seconds.
requeuetimer = 30,
meshchange [table][optional] Will change mesh based on below options. Will revert to default / selected mesh when a loading screen is detected. This is useful for fights such as titan where the platform shrinks at certain %.
meshchange = { [1] = {type = "percent", percent = 50, newmesh = "The Naval - Smallest", desc = "switch to smallest platform"}, [2] = {type = "castid", castid = 1234, newmesh = "This that t'other", reverttimer = 20, desc = "specific avoidance requirement"}, },
togglewalk [table][optional] useful when you need precise navigation such as in Dohn Mheg. When inside of the polygon and on the specified mesh, walking will be enabled. If not on the specified mesh, or outside of the polygon, normal running speed it used.
togglewalk = { [1] = {polygon= {[1] = {x = 12, z = 21}, [2] = {x = 21, z = 12}, [3] = {x = 38, z = 38}}, meshname = "The Naval - Smallest, desc = "switch to smallest platform"}, },
excludeavoid [table][optional] Way to stop my avoidance avoiding some aoes, such as those that are part of a stack marker. channelingid of each cast separated by a comma.
excludeavoid = {1,2,3,4,5}
dontexcludeaoe [table][optional] Way to ensure aoes are avoided. This was added for large aoes that are greater than the auto exclude distance shown in the avoidance tab. An example is Zodiark's charge across the platform, adding that aoe here means it will be avoided, while keeping the default 30.
dontexcludeaoe = {1234,587,489,}
Through advancedavoid, you can add avoidance through the below method too. It is useful if you need to enable and disable avoidance of certain aoes:
KitanoiSettings.DFIndexedExcludeAvoid[aoeid] = true -- excludes an aoe KitanoiSettings.DFIndexedExcludeAvoid[aoeid] = nil -- removes an excluded aoe (that you have previously added)
tankspecific [table][optional] Used when you have 2 tanks needing to tank separate enemies at specific locations. Will auto turn on tank stance (will get turned off again on OT) get 100% aggro, then move to designated position.
tankspecific = { [1] = { who = "tank1", type = "tankat", pos = {x=1,y=2,z=3}, contentid = 12345, }, [2] = { who = "tank2", type = "tankat", pos = {x=3,y=2,z=1}, contentid = 54321, }, [3] = { who = "tank1", type = "forcetarget", contentid = 12345, } [4] = { who = "tank2", type = "forcetarget", contentid = 54321, } }
tankbuster [table][optional] All characters except tank or the character that is currently has 100% aggro will avoid.
tankbuster = {1,2,3,4,5}
tankat [table][optional] Allows you to specify a position, % from and % to to tank at that position. This is useful if you need to be able to move the boss at certain %. This will only work for tanks, or those who are at the top of the aggro list.
tankat= { [1] = {contentid = 12345, frompercent = 100, topercent = 95, pos = {x = 1, y = 2, z = 3}, desc = "tank boss 12345 at this pos from 100-95%"}, },
puddledata [table][optional] Specify spells that leave puddles on the floor. Provide the channelingid, radius, and duration. This will tell my avoidance system to not avoid into this puddle.
puddledata= { [1] = {castid = 12345, radius= 5, duration = 15, type = "player", desc = "puddle left by boss 2 when casting super fire move at player"}, [2] = {castid = 15545, radius= 5, duration = 15, type = "ground", desc = "puddle that appears at random points on ground"}, },
pullenemyoutofpuddle [bool][optional] Used in combination with puddledata. Useful for the final boss of Brayflox Longstop to pull Aiatar out of the puddles. Isn't perfect, but is successful.
pullenemyoutofpuddle = true,
incombatinteract [table][optional]
incombatinteract= { [1] = {interactid= 12345, type= "interact", req = {castingid = 1208, desc = "isegbind casting"}, who = "closest", desc = "interact with something"}, [2] = {interactid= "12345;8484;4984", type= "interact", who = "closest", desc = "interact with something"}, [3] = {interactid= 54345, type= "move", who = "closest", buffid = 90, pos = {x = 1, y = 2, z = 3}, dist = 15, action = {type = 1, actionid = 24}, desc = "interact and move with something"}, },
avoidentity[table][optional] - Used to avoid moving entities, like those on the second boss in Stone Vigil. Set the radius slightly larger than where the aoe is.
avoidentity= { [1] = {contentid= 12345, radius = 5, type = "circle"}, [2] = {contentid= 12345, radius = 5}, [3] = {contentid= 52341, type = "rectangle"}, },
forcemeleerange[table][optional]
forcemeleerange= {12345,65421,47811}
faceenemyaway[table][optional]
faceenemyaway = {12345,65421,47811}
Tank, when at 100% aggro will attempt to face away any enemy with a matching contentid away from the party.
tethers - handles tethers
tethers = { [1] = {id = 12, type = "avoid", radius = 16, who = "entityone", duration = 6, desc = "First Boss Jumps"}, [2] = {id = 12, type = "avoid", radius = 16, who = "entitytwo", duration = 6, desc = "First Boss jumps"}, [3] = {id = 17, type = "move", priority = 1, pos = {[1] = {[1] = {x = -458.90, y = 1.19, z = -531.26}, [2] = {x = -441.77, y = 0, z = -532.75},}, [2] = {[1] = {x = -458.90, y = 1.19, z = -531.26}, [2] = {x = -441.77, y = 0, z = -532.75},}, [3] = {[1] = {x = -458.90, y = 1.19, z = -531.26}, [2] = {x = -441.77, y = 0, z = -532.75},}, [4] = {[1] = {x = -458.90, y = 1.19, z = -531.26}, [2] = {x = -441.77, y = 0, z = -532.75},}}, desc = "Second Boss normal tether"}, [4] = {id = 79, type = "move", priority = 2, pos = {[1] = {[1] = {x = -462.99, y = -2.38, z = -544.31}, [2] = {x = -436.37, y = 2.38, z = -543.47},}, [2] = {[1] = {x = -467.53, y = 2.38, z = -537.02}, [2] = {x = -431.78, y = 0, z = -535.72},}, [3] = {[1] = {x = -467.04, y = -1.19, z = -525.08}, [2] = {x = -431.71, y = -1.19, z = -527.03},}, [4] = {[1] = {x = -463.28, y = -1.19, z = -517.52}, [2] = {x = -435.81, y = 0, z = -518.89},}}, desc = "Second Boss red tether"}, },
limitbreak
limitbreak = { [1] = {contentid = 9505, percent = 15, level = 1, type = "melee"}, [2] = {contentid = 9511, percent = 15, level = 2, type = "melee"}, [3] = {contentid = 1234, percent = 95, level = 1, type = "squadron"}, },
dontcastwhenlb[optional][bool]
will pause ACR/skill profile (doesn't work with MCR) when conditions met to allow LB to be cast faster.
tankswap [optional][table]
tankswap = {9999,4444},
castid or channelingid when you wish to tank swap. Ideally you want to turn autostances off in your skill profiles / acr and use the below option as well and let the addon handle tank stances.
autotankstance [optional][bool]
autotankstance= true,
Only useful in dungeons where multiple tanks are in use. Ensure auto tank stances are turned off in skill profiles / acrs.
ignoretarget [optional][table]
ignoretarget = {2667,1234},
Comma separated contentid - will exclude these contentids from being targeted.
enemylos [optional][bool]
enemylos = false,
true or false - false allows targeting through walls. true will only target when los
avoidancetype
avoidancetype = 1, --new avoidancetype = 2, --old
This code will allow you to determine which avoidance type is used for the profile. For instance, I use new everywhere, but in Malikah's Well boss 3, old is better. This allows me to use the new option in avoidance tab, but old avoidance in that dungeon.
largerpulls [tbl][optional]
largerpulls = { distance = 45, }, --It is only designed to work in a proper party (or a solo tank), it is no use for solo farming dungeons. --It will not be made available as a toggle option to be running on any dungeon. It will not be added to my trust profiles. --This is something that you can use in your own profiles. It is limited in how it works, if you find yourself running into wall, lower the distance.
dontcastwhenmoving [bool][optional]
dontcastwhenmoving = true,
forces skillprofiles / acrs to not cast when your character is moving. Doesn't work with MCR
staybehindentity[optional][table]
staybehindentity = {1234,4567,7890,0123}
Comma separated contentid.
Will move your character behind the boss provided the following conditions are met:
mapeffects [optional][table]
mapeffects = { [1] = { contentid = "123;654", -- semicolon separated string a1 = 43, a2 = 128, a3 = 2, luacode = "d('This is just an example, and would run one time when the mapeffect change happens')", }, },
This data is available from the console. This will be used for things such as snakes in Zodiark, triangles in WoL etc. More details in Argus wiki.
This mapeffect data will also be stored to:
local stringed = IsNull(a1,"none") .. IsNull(a2,"none") .. IsNull(a3,"none") KitanoiSettings.SavedMapEffects[tostring(stringed)] = { a1 = IsNull(a1,"none"), a2 = IsNull(a2,"none"), a3 = IsNull(a3,"none"), timeadded = Now() }
if (KitanoiSettings.SavedMapEffects["153none"] ~= nil and TimeSince(KitanoiSettings.SavedMapEffects["153none"].timeadded) < 3000) then --do something end if (KitanoiSettings.SavedMapEffects["153512"] ~= nil and TimeSince(KitanoiSettings.SavedMapEffects["153512"].timeadded) < 3000) then --do something end
[Kitanoi Functions] - Map Effect - a1: 43 - a2: 4 - a3: 8
KitanoiFuncs.LoadDungeonTbl(tbl) Allows you to load dungeon profiles from lua. This would allow you to set up an addon to autoload dungeon profiles based on mapid for instance.
Variables to use with custom lua
KitanoiSettings.DFTimer[int] KitanoiSettings.DFTimer2[int] KitanoiSettings.DFTimer3[int] KitanoiSettings.DFTimer4[int] KitanoiSettings.DFTimer5[int] KitanoiSettings.StoreVar[tbl] KitanoiSettings.StoreVar2[tbl] KitanoiSettings.StoreVar3[tbl] KitanoiSettings.StoreVar4[tbl] KitanoiSettings.StoreVar5[tbl]
Adding areas to my avoidance table
Circles:
if (KitanoiFuncs.puddledata[e.id] == nil) then KitanoiFuncs.puddledata[e.id] = {entity = entityid, pos = entity.pos, radius = 10, aoeID = 468464, name = "Twinning puddles", duration = Now() + 10000} end
Rectangles:
if (KitanoiFuncs.CurrentAOEs[entity.id] == nil) then KitanoiFuncs.AvoidRectangle2(entity.id,length,width,timeinms) end
if (KitanoiFuncs.CurrentAOEs[key] == nil) then KitanoiFuncs.AvoidRectangleSpecific(pos,heading,width,key) --adds for 1 second end
key - unique identifier you want to use
heading - face the way you want the area to be classed as an aoe. Player.pos.h
width - how wide
length is 50 by default - no way to change it.
Check if there is a record before adding unless it is a moving entity and you need the points updated.
Boss | Mechanic | a1 | a2 | a3 | notes |
Magitek Core (Paglth'an) | East Laser | 10 | 16 | 32 | Right laser as you look at boss |
Magitek Core (Paglth'an) | Center Laser | 9 | 16 | 32 | Center laser |
Magitek Core (Paglth'an) | West laser | 8 | 16 | 32 | Left laser as you look at boss |
Svarbhanu (Vanaspati) | Pattern OOXO | 10 | 1 | 2 | First meteor is missing at X |
Svarbhanu (Vanaspati) | Pattern OXOO | 11 | 1 | 2 | First meteor is missing at X |
Caustic Grebuloff (The Dead Ends) | Northerly Wind | 43 | 15 | 12 | |
Caustic Grebuloff (The Dead Ends) | Southerly Wind | 43 | 16 | 256 | |
Leannan Sith | *AA | 11 | 1024 | 2048 | See AA below |
Leannan Sith | *AB | 11 | 1 | 2 | See AB below |
—————————————————————
Warrior of Light Extreme has 84 possible 3 MapEffect combinations. Fights like this won't be added here.
*AB OXXO XOOX XOXO OXOX *AA OXXO XOOX OXOX XOXO X = grass
Tasks happen in the following order:
NPC Repair > GC exchange > Item Puchase
lua conditions must always return boolean. Start the condition with return
reactions = { [1] = { cause = "return KitanoiFuncs.ScanForCaster2(16659) and ((ActionList:Get(1,7548).usable and not ActionList:Get(1,7548).isoncd) or (ActionList:Get(1,7559).usable and not ActionList:Get(1,7559).isoncd))", effect = "if (ActionList:Get(1,7548).usable and not ActionList:Get(1,7548).isoncd) then ActionList:Get(1,7548):Cast(Player) end if (ActionList:Get(1,7559).usable and not ActionList:Get(1,7559).isoncd) then ActionList:Get(1,7559):Cast(Player) end ", name = "KB immunity", }, },
Example to stop you attacking until you react a destination:
local objpullloc = { [1] = {x=1,y=2,z=3}, } local nextobj = KitanoiFuncs.GetFirstNotCompleted() if (Player.incombat and nextobj~=10 and objpullloc[nextobj] ~= nil and math.distance2d(Player.pos,objpullloc[nextobj])>5 and KitanoiFuncs.HowManyAOES() == 0) then return true end
Example from Sogigak on Discord to make larger pulls:
function customfunction() local DiedOrDungeonStart = math.distance2d(Player.pos, { x = 163.33, y = 0.1, z = 80.07 }) < 10 if BigPull == nil or DiedOrDungeonStart then BigPull = { [1] = false, [2] = false } end local PullPositions = { [1] = { objective = 1, pos = { x = 44.26, y = -8.58, z = 32.19 } }, [2] = { objective = 2, pos = { x = -123.84, y = -30.66, z = -164.22 } } } if KitanoiFuncs.GetFirstNotCompleted() == 1 and Player.incombat and not BigPull[1] and KitanoiFuncs.HowManyAOES() == 0 then local PullPosition = PullPositions[1].pos; if math.distance2d(Player.pos, PullPosition ) > 5 then Player:MoveTo(PullPosition.x, PullPosition.y, PullPosition.z) KitanoiSettings.avoidingtime = Now() + 10000 gACREnabled = false; return else BigPull[1] = true gACREnabled = true return end end if KitanoiFuncs.GetFirstNotCompleted() == 3 and Player.incombat and not BigPull[2] and KitanoiFuncs.HowManyAOES() == 0 then local PullPosition = PullPositions[2].pos; if math.distance2d(Player.pos, PullPosition) > 5 then Player:MoveTo(PullPosition.x, PullPosition.y, PullPosition.z) KitanoiSettings.avoidingtime = Now() + 10000 gACREnabled = false; return else BigPull[2] = true gACREnabled = true return end end end
This replaces advancedavoid where you need abilities to be used. For anything else, use advancedavoid.
If scanning for a cast, please use:
KitanoiFuncs.ScanForCaster2(ID,maxtimer,mintimer,returntbl) --channels local channelexample = KitanoiFuncs.ScanForCaster2(1234) -- returns bool if any entity is currently channeling 1234 local channelexample2 = KitanoiFuncs.ScanForCaster2(1234,nil,nil,true) -- returns table of all entities currently channeling 1234 KitanoiFuncs.ScanForCast2(ID,maxtimer,mintimer,returntbl) --instant casts local castexample = KitanoiFuncs.ScanForCast2(1234,2) --returns bool if any entity has cast 1234 in the past 2 seconds local castexample2 = KitanoiFuncs.ScanForCast2(1234,2,nil,true) --returns table of any entitie that have cast 1234 in the past 2 seconds
timeline = { [1] = { contentids = "1234;4321", --semicolon separated contentids starttime = 1000, --time in milliseconds that the code should run endtime = 3000, --time in milliseconds that the code should stop running luacode = "Player:MoveTo(x,y,z) KitanoiSettings.avoidingtime = Now()", }, [2] = { contentids = "1234;4321", --semicolon separated contentids starttime = 25000, --time in milliseconds that the code should run endtime = 30000, --time in milliseconds that the code should stop running luacode = "Player:MoveTo(x,y,z) KitanoiSettings.avoidingtime = Now()", }, },
Uses KitanoiSettings.InCombatTimer for starttime and endtime
TimeSince(KitanoiSettings.InCombatTimer)
syncon = { [1] = { details = "sync combat timer to 190 seconds on annihilation cast", cause = "return KitanoiFuncs.ScanForCast2(33024,1)", time = 190000, } },
This syncs KitanoiSettings.InCombatTimer to the time specified when the cause returns true
TimeSince(KitanoiSettings.InCombatTimer)
customgui = [[ GUI:Text('Testing The Custom GUI') if (test1==nil) then test1 = 1 end test1,changed = GUI:InputInt('##test1',test1) if (test2==nil) then test2 = 1 end test2, changed = GUI:RadioButton('Random 1##test21', test2,1) GUI:SameLine() test2, changed = GUI:RadioButton('Random 2##test22', test2,2) if (test3==nil) then test3 = "" end test3,changed = GUI:InputText("Search##test3",test3) if (test4i == nil) then test4i = 1 end test4c = {"none","one","two","three"} test4i, changed = GUI:Combo("", test4i, test4c) GUI:Button("Some Button") ]],
Showing dungeons from your code inside of KDF:
https://wiki.mmominion.com/doku.php?id=kdf_3rd_party
As of May 2021 - new options have been added that allow you to write your own functions in lua and call it in dungeon framework. If there are needs for general functions I will look to add them. But any bespoke functions are for the user to create.
Any requests for functions will need at minimum the following information: (This information is used to see the mechanic you need handling, but will be still be adhearing to the first point made above.)
Dungeon Name
Boss Name
Action Name
Expectations / How to handle it