--[[
jParty v1.11.20beta
Author: Zangetsu for SolarStrike http://www.solarstrike.net
Based on Lisa (Big thanks!), rock5 and JackBlonder work.
Files:
- rom/scripts/userfunctions/userfunctions_jparty.lua
- rom/scripts/waypoints/jparty.xml
- rom/scripts/logs/jparty.log (Currently disabled)
How to use: Place previous file into the right place, then add and complete these line on your Player.xml
jParty Parameters
The bot will assist this member if a fight is engaged
The bot will follow this member
The bot will keep this distance with the BotFollowed (100 is already a lot, make test before increasing)
The bot will heal
The bot will Fight the target of BotAssist if in combat
The bot will loot
Your main heal
Your Big heal
Your regen (The bot will only regen if jParty_RegenBuffName is not found on party members and if IN combat
The name of your buff's regen
If you want a debug file (true or false) <-- Currently disabled.
To make your bot sell stuff, have a merchant targeted, put the Icon 8 on its head, then wait a bit and remove it.
To make your character speak with a NPC, target the NPC and choose options put:
- Icon 1 if you want the bot choose the option 1
- Icon 2 if you want the bot choose the option 2
- Icon 3 if you want the bot choose the option 3
- Icon 5 if you want the bot choose the option 4
- Icon 5 if you want the bot choose the option 5
- Icon 6 if you want the bot choose the option 6
- Icon 7 if you want the bot choose the option 7
IMPORTANT: Remember to target, put the icon you need, wait a bit and put the icon on someone else. Or else, the bot will keep spamming the choice depending the Icon.
I know it's not perfect, but until I find a way, it's like that :S
--]]
if(settings == nil ) then
include("settings.lua");
end
function PartyDisplay(DisplayType, DisplayName)
if DisplayType == "Master" then
LastPartyMasterDisplayed = true
cprintf(cli.yellow, "jParty: My Master is: ".. DisplayName .."\n");
end
if DisplayType == "Assist" then
LastPartyAssistDisplayed = true
cprintf(cli.yellow, "jParty: My Assist is: ".. DisplayName .."\n");
end
if DisplayType == "Followed" then
LastPartyFollowedDisplayed = true
cprintf(cli.yellow, "jParty: My Followed is: ".. DisplayName .."\n");
end
if DisplayType == "MaxPartyMembers" then
LastMaxPartyMembersDisplayed = true
cprintf(cli.yellow, "jParty: There is: ".. DisplayName .." party's members.\n\n");
end
end -- End of function PartyDisplay
-- PartyFollow() This is the closest thing I found to the need :/
function PartyFollow(Followed, BotX, BotZ, FollowedX, FollowedZ, FollowedName, MasterX, MasterZ, MasterName, AssistX, AssistZ, AssistName)
AWayTooFarDistance = settings.profile.options.jParty_FollowingDistance + 100
if(distance(BotX, BotZ, FollowedX, FollowedZ) > settings.profile.options.jParty_FollowingDistance) then
cprintf(cli.turquoise, "jParty: " .. FollowedName .. " is too far, I need to follow him. \n\n");
player:moveTo(CWaypoint(FollowedX, FollowedZ), true)
if(distance(BotX, BotZ, FollowedX, FollowedZ) > AWayTooFarDistance) then -- A lot too far
cprintf(cli.turquoise, "jParty: My Followed, " .. FollowedName .. ", is a way too far, I try to follow my Master: "..MasterName.." \n\n");
player:moveTo(CWaypoint(MasterX, MasterZ), true)
if distance(BotX, BotZ, FollowedX, FollowedZ) > AWayTooFarDistance and distance(BotX, BotZ, MasterX, MasterZ) > AWayTooFarDistance then
cprintf(cli.turquoise, "jParty: My Followed, " .. FollowedName .. ", and my Master, " ..MasterName..", are a way too far. I try to follow my Assist: "..AssistName.." \n\n");
player:moveTo(CWaypoint(AssistX, AssistZ), true)
if distance(BotX, BotZ, AssistX, AssistZ) > settings.profile.options.jParty_FollowingDistance then -- Everyone is too far away
-- All are too far. Maybe zoned?
cprintf(cli.turquoise, "jParty: Everyone seems too far, I'm trying last "..FollowedName.."'s position and I'll just press FORWARD until I can target someone.\n\n")
player:moveTo(CWaypoint(LastPartyFollowX, LastPartyFollowZ), true)
player:target(Followed)
if player:getTarget().Name ~= FollowedName and player:getTarget().Name ~= MasterName and player:getTarget().Name ~= AssistName then
keyboardPress(key.VK_Z);
end
end
end
end
end
end --End of function PartyFollow()
-- GetTargetIcon() -- This isn't clean code I guess, but it's working.
function GetTargetIcon(TargetID)
local obj = nil;
local objectList = CObjectList();
objectList:update();
for i = 0,objectList:size() do
obj = objectList:getObject(i);
if(CPawn(obj.Address).Id == TargetID) then
return CPawn(obj.Address):GetPartyIcon();
end
end
end
-- PartyNPC() - Check if the target is a NPC | With loop is messing a bit, you have to remove the icon quick enough or it will loop and choose 1, 1, 1 til the icon is on the NPC and the icon is my target. I need no find a better way.
function PartyNPC(Master, MasterTarget)
if MasterTarget ~= nil then
player:target(MasterTarget)
local MyTargetName = player:getTarget().Name
local MyTargetID = CPawn(player:getTarget().Address).Id
if player:getTarget().Type == 4 then -- My Target is a NPC
cprintf(cli.lightgreen, "jParty: My Target is a NPC (".. MyTargetName.."). I'm checking if it have an Icon.\n");
local MyTargetIcon = GetTargetIcon(MyTargetID)
if MyTargetIcon ~= nil and MyTargetIcon ~= 0 then
if MyTargetIcon == 1 then -- Talk to NPC and select choice 1
player:target_NPC(MyTargetName);
RoMScript("ChoiceOption(1);")
elseif MyTargetIcon == 2 then -- Talk to NPC and select choice 2
player:target_NPC(MyTargetName);
RoMScript("ChoiceOption(2);")
elseif MyTargetIcon == 3 then -- Talk to NPC and select choice 3
player:target_NPC(MyTargetName);
RoMScript("ChoiceOption(3);")
elseif MyTargetIcon == 4 then -- Talk to NPC and select choice 4
player:target_NPC(MyTargetName);
RoMScript("ChoiceOption(4);")
elseif MyTargetIcon == 5 then -- Talk to NPC and select choice 5
player:target_NPC(MyTargetName);
RoMScript("ChoiceOption(5);")
elseif MyTargetIcon == 6 then -- Talk to NPC and select choice 6
player:target_NPC(MyTargetName);
RoMScript("ChoiceOption(6);")
elseif MyTargetIcon == 7 then -- Talk to NPC and select choice 7
player:target_NPC(MyTargetName);
RoMScript("ChoiceOption(7);")
elseif MyTargetIcon == 8 then -- The NPC is a merchant, sending stuff.
cprintf(cli.lightgreen, "jParty: Icon is 8. ".. MyTargetName.." is a merchant, I'm going to sell.\n");
if 3 > inventory:itemTotalCount(0) then
player:merchant(MyTargetName);
else
cprintf(cli.lightgreen, "jParty: I have enough space in my bag.\n");
end
else
end
end
end
end
end -- End of PartyNPC()
-- PartyHealing()
function PartyHealing(MemberToHeal)
MemberToHeal:update()
if (30 > player.MP/player.MaxMP*100) then
player:checkPotions();
cprintf(cli.turquoise, "jParty: I have low MP [".. player.MP .."/".. player.MaxMP .."MP]\n I'm taking potions.\n");
yrest(1000);
else
if (70 > MemberToHeal.HP/MemberToHeal.MaxHP*100 and MemberToHeal.HP/MemberToHeal.MaxHP*100 > 50) then
player:target(MemberToHeal)
yrest(300)
player:cast(settings.profile.options.jParty_Heal)
cprintf(cli.lightblue, "jParty: Healing ".. MemberToHeal.Name .."\n");
yrest(300)
elseif (50 > MemberToHeal.HP/MemberToHeal.MaxHP*100) then
player:target(MemberToHeal)
yrest(300)
player:cast(settings.profile.options.jParty_BigHeal)
cprintf(cli.lightblue, "jParty: Big heals on ".. MemberToHeal.Name .."\n");
yrest(300)
end
MemberToHeal:updateBuffs();
if not MemberToHeal:hasBuff(settings.profile.options.jParty_RegenBuffName) and player.Battling then
player:target(MemberToHeal)
yrest(300)
player:cast(settings.profile.options.jParty_Regen)
cprintf(cli.lightblue, "jParty: Regen on ".. MemberToHeal.Name .."\n");
end
end
end -- End of PartyHealing()
-- PartyDPSing() is the function that make your bot DPS the mob that jParty_BotAssist is targeting and fighting
function PartyDPSing(PartyAssist) -- Maybe need some improvements
if player.Battling then
if (30 > player.MP/player.MaxMP*100) then
player:checkPotions();
cprintf(cli.turquoise, "jParty: I have low MP [".. player.MP .."/".. player.MaxMP .."MP]\n I'm taking potions...\n");
yrest(1000);
else
if PartyAssist ~= nil then -- Checking if Assist exist.
PartyAssist:update()
player:target(PartyAssist.TargetPtr)
MyCurrentTargetToDPS = player:getTarget();
player:checkSkills(true);
MyCurrentTargetNameToDPS = player:getTarget().Name;
if MyCurrentTargetNameToDPS ~= "" then
player:fight();
cprintf(cli.lightred, "jParty: Fighting [".. MyCurrentTargetNameToDPS .."]\n");
yrest(300);
end
end
end
end
end -- End of PartyDPSing()
-- PartyLoot() Function for looting mobs
function PartyLoot() -- Need to tweak it to make the boot loot when mobs are dead. Need some improvements
--player:loot();
player:lootAll();
end
-- PartyOrders() Using EventMonitor to execute simple command from Party chat and Bot's master
function PartyOrders()
local time, moreToCome, name, msg = EventMonitorCheck("jPartyOrdersMonitor", "4,1")
if time ~= nil then
if name == settings.profile.options.jPartyLeaderName then
--You can set your orders here.
if string.find(msg,"rest mp") then
repeat
yrest(1000)
until ((player.MP*100)/player.MaxMP) == 100
end
if string.find(msg,"drop party") then
RoMScript("LeaveParty();");
end
if string.find(msg,"go chan 1") then
RoMScript("ChangeParallelID(1);");
end
if string.find(msg,"go chan 2") then
RoMScript("ChangeParallelID(2);");
end
if string.find(msg,"go chan 3") then
RoMScript("ChangeParallelID(3);");
end
end
end
end
function jPartyMain()
if memoryReadBytePtr(getProc(),addresses.loadingScreenPtr, addresses.loadingScreen_offset) ~= 0 then
cprintf(cli.yellow, "jParty: Loading screen");
repeat
cprintf(cli.yellow, "...");
yrest(1000)
until memoryReadBytePtr(getProc(),addresses.loadingScreenPtr, addresses.loadingScreen_offset) == 0
end
player:update();
--If I'm not in a party, I wait for an invite
---if player.InParty ~= true then
if RoMScript("UnitIsPlayer('party1');") ~= true then
cprintf(cli.yellow, "jParty: I'm not in a Party! \n");
--PartyWaitForInvite() Need to find how to get the name of the player who's inviting in Party
else
_timexx = os.time()
PartyTable() -- populate party member table
local i = 2
MaxPartyMembers = 2
while not(i >= 7 ) do
local partyID = i-1 -- Trick because 1 is player in memory but party1 is the first player in the party
if RoMScript("UnitIsPlayer('party" .. partyID .. "');") then
if partymemberpawn[i] ~= nil then -- Checking if there is existing
if MaxPartyMembers > i then
MaxPartyMembers = i
end
partymemberpawn[i]:update()
if partymemberpawn[i].Name == settings.profile.options.jParty_BotMaster then
PartyMaster = partymemberpawn[i]
end
if partymemberpawn[i].Name == settings.profile.options.jParty_BotAssist then
PartyAssist = partymemberpawn[i]
end
if partymemberpawn[i].Name == settings.profile.options.jParty_BotFollowed then
PartyFollowed = partymemberpawn[i]
end
if settings.profile.options.jParty_BotHealer then
-- Checking healing needed
PartyHealing(partymemberpawn[i])
-- Checking selfhealing needed
PartyHealing(player)
end
end
end
i = i + 1
end -- End of loop
if LastPartyMasterDisplayed ~= true and PartyMaster ~= nil then
if LastPartyMasterName ~= PartyMaster.Name then
PartyDisplay("Master", PartyMaster.Name)
end
end
if LastPartyAssistDisplayed ~= true and PartyAssist ~= nil then
if LastPartyAssistName ~= PartyAssist.Name then
PartyDisplay("Assist", PartyAssist.Name)
end
end
if LastPartyFollowedDisplayed ~= true and PartyFollowed ~= nil then
if LastPartyFollowedName ~= PartyFollowed.Name then
PartyDisplay("Followed", PartyFollowed.Name)
end
end
if LastMaxPartyMembersDisplayed ~= true then
if LastMaxPartyMembers ~= MaxPartyMembers then
PartyDisplay("MaxPartyMembers", MaxPartyMembers)
end
end
if PartyFollowed ~= nil then
-- Checking if I'm not too far of PartyFollowed
PartyFollow(PartyMaster, player.X, player.Z, PartyFollowed.X, PartyFollowed.Z, PartyFollowed.Name, PartyMaster.X, PartyMaster.Z, PartyMaster.Name, PartyAssist.X, PartyAssist.Z, PartyAssist.Name)
end
if settings.profile.options.jParty_BotLooter then
-- Looting - Need a lot of improvements
PartyLoot()
end
if PartyMaster ~= nil then
-- Checking if the target of my Master is a NPC
PartyNPC(PartyMaster, PartyMaster.TargetPtr)
end
if settings.profile.options.jParty_BotDPSer then
if PartyAssist ~= nil then
-- Checking if fighting needed
PartyDPSing(PartyAssist)
end
end
if PartyMaster ~= nil then
-- Monitoring Master's orders in party chat
PartyOrders()
end
end -- End of "If I'm in Party"
end -- End of jPartyMain()
function SaveLastFollowedPos() -- Fast Position save
player:update()
--if player.InParty ~= true then
--else
_timexx = os.time()
PartyTable() -- populate party member table
local i = 2
while not(i >= 7 ) do
local partyID = i-1 -- Trick because 1 is player in memory but party1 is the first player in the party
if RoMScript("UnitIsPlayer('party" .. partyID .. "');") then
if partymemberpawn[i] ~= nil then -- Checking if there is existing
partymemberpawn[i]:update()
if partymemberpawn[i].Name == settings.profile.options.jParty_BotFollowed then
LastPartyFollowX = partymemberpawn[i].X
LastPartyFollowZ = partymemberpawn[i].Z
end
end
end
i = i + 1
end -- End of loop
--end -- End of "If I'm in Party"
end -- End of SaveLastFollowedPos() function
function startjParty()
if settings.profile.options.jParty_BotMaster == nil then
error("jParty: You must set the jParty_BotMaster in your profile file!");
elseif settings.profile.options.jParty_BotAssist == nil then
error("jParty: You must set the jParty_BotAssist in your profile file!");
elseif settings.profile.options.jParty_BotFollowed == nil then
error("jParty: You must set the jParty_BotFollowed in your profile file!");
elseif settings.profile.options.jParty_FollowingDistance == nil then
error("jParty: You must set the jParty_FollowingDistance in your profile file!");
elseif settings.profile.options.jParty_BotHealer == nil then
error("jParty: You must set the jParty_BotHealer in your profile file!");
elseif settings.profile.options.jParty_BotDPSer == nil then
error("jParty: You must set the jParty_BotDPSer in your profile file!");
elseif settings.profile.options.jParty_BotLooter == nil then
error("jParty: You must set the jParty_BotLooter in your profile file!");
elseif settings.profile.options.jParty_Heal == nil and settings.profile.options.jParty_BotHealer == true then
error("jParty: You must set the jParty_Heal in your profile file!");
elseif settings.profile.options.jParty_BigHeal == nil and settings.profile.options.jParty_BotHealer == true then
error("jParty: You must set the jParty_BigHeal in your profile file!");
elseif settings.profile.options.jParty_Regen == nil and settings.profile.options.jParty_BotHealer == true then
error("jParty: You must set the jParty_Regen in your profile file!");
elseif settings.profile.options.jParty_RegenBuffName == nil and settings.profile.options.jParty_BotHealer == true then
error("jParty: You must set the jParty_RegenBuffName in your profile file!");
else
unregisterTimer("jPartyTimer");
unregisterTimer("jPartySaveLastFollowedPosTimer");
cprintf(cli.yellow, "jParty have been started.\n");
EventMonitorStart("jPartyOrdersMonitor", "CHAT_MSG_PARTY");
EventMonitorStart("jPartyCastLootMonitor", "LOOT_ITEM_SHOW");
registerTimer("jPartyTimer", 1000, jPartyMain);
registerTimer("jPartySaveLastFollowedPosTimer", 300, SaveLastFollowedPos);
end
end