1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-20 19:57:46 +00:00

Started implementing retainers. Added a instanced retainer spawn. Documented retainer scripts.

This commit is contained in:
Filip Maj 2017-09-05 12:37:23 -04:00
parent b5054debea
commit f437b36f5a
19 changed files with 313 additions and 34 deletions

View file

@ -888,8 +888,8 @@ namespace FFXIVClassic_Map_Server
int count = 0; int count = 0;
while (reader.Read()) while (reader.Read())
{ {
player.charaWork.status[count] = reader.GetUInt16(0); player.charaWork.status[count] = reader.GetUInt16("statusId");
player.charaWork.statusShownTime[count] = reader.GetUInt32(1); player.charaWork.statusShownTime[count] = reader.GetUInt32("expireTime");
} }
} }
@ -1924,6 +1924,53 @@ namespace FFXIVClassic_Map_Server
} }
} }
public static Tuple<uint, uint, string> GetRetainer(Player player, int retainerIndex)
{
Tuple<uint, uint, string> data = null;
using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
{
try
{
conn.Open();
string query = @"
SELECT server_retainers.id as retainerId, server_retainers.name as name, actorClassId FROM characters_retainers
INNER JOIN server_retainers ON characters_retainers.retainerId = server_retainers.id
WHERE characterId = @charaId
ORDER BY id
LIMIT 1 OFFSET @retainerIndex
";
MySqlCommand cmd = new MySqlCommand(query, conn);
cmd.Parameters.AddWithValue("@charaId", player.actorId);
cmd.Parameters.AddWithValue("@retainerIndex", retainerIndex-1);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
uint retainerId = reader.GetUInt32("retainerId");
string name = reader.GetString("name");
uint actorClassId = reader.GetUInt32("actorClassId");
data = new Tuple<uint, uint, string>(retainerId, actorClassId, name);
}
} }
}
catch (MySqlException e)
{
Program.Log.Error(e.ToString());
}
finally
{
conn.Dispose();
}
return data;
}
}
}
} }

View file

@ -82,6 +82,7 @@
<Compile Include="actors\chara\npc\ActorClass.cs" /> <Compile Include="actors\chara\npc\ActorClass.cs" />
<Compile Include="actors\chara\npc\NpcWork.cs" /> <Compile Include="actors\chara\npc\NpcWork.cs" />
<Compile Include="actors\chara\AetheryteWork.cs" /> <Compile Include="actors\chara\AetheryteWork.cs" />
<Compile Include="actors\chara\npc\Retainer.cs" />
<Compile Include="actors\chara\player\Equipment.cs" /> <Compile Include="actors\chara\player\Equipment.cs" />
<Compile Include="actors\chara\player\Inventory.cs" /> <Compile Include="actors\chara\player\Inventory.cs" />
<Compile Include="actors\chara\Work.cs" /> <Compile Include="actors\chara\Work.cs" />
@ -92,6 +93,7 @@
<Compile Include="actors\EventList.cs" /> <Compile Include="actors\EventList.cs" />
<Compile Include="actors\group\GLContentGroup.cs" /> <Compile Include="actors\group\GLContentGroup.cs" />
<Compile Include="actors\group\ContentGroup.cs" /> <Compile Include="actors\group\ContentGroup.cs" />
<Compile Include="actors\group\RetainerMeetingRelationGroup.cs" />
<Compile Include="actors\group\Work\ContentGroupWork.cs" /> <Compile Include="actors\group\Work\ContentGroupWork.cs" />
<Compile Include="actors\group\Work\GlobalTemp.cs" /> <Compile Include="actors\group\Work\GlobalTemp.cs" />
<Compile Include="actors\group\Group.cs" /> <Compile Include="actors\group\Group.cs" />
@ -260,6 +262,10 @@
<Compile Include="packets\send\recruitment\EndRecruitmentPacket.cs" /> <Compile Include="packets\send\recruitment\EndRecruitmentPacket.cs" />
<Compile Include="packets\send\recruitment\RecruiterStatePacket.cs" /> <Compile Include="packets\send\recruitment\RecruiterStatePacket.cs" />
<Compile Include="packets\send\recruitment\StartRecruitingResponse.cs" /> <Compile Include="packets\send\recruitment\StartRecruitingResponse.cs" />
<Compile Include="packets\send\search\ItemSearchResult.cs" />
<Compile Include="packets\send\search\ItemSearchResultsEndPacket.cs" />
<Compile Include="packets\send\search\ItemSearchResultsBodyPacket.cs" />
<Compile Include="packets\send\search\ItemSearchResultsBeginPacket.cs" />
<Compile Include="packets\send\SendMessagePacket.cs" /> <Compile Include="packets\send\SendMessagePacket.cs" />
<Compile Include="packets\send\SetMapPacket.cs" /> <Compile Include="packets\send\SetMapPacket.cs" />
<Compile Include="packets\send\SetMusicPacket.cs" /> <Compile Include="packets\send\SetMusicPacket.cs" />

View file

@ -83,7 +83,7 @@ namespace FFXIVClassic_Map_Server.Actors
public SubPacket CreateNamePacket() public SubPacket CreateNamePacket()
{ {
return SetActorNamePacket.BuildPacket(actorId, displayNameId, displayNameId == 0xFFFFFFFF | displayNameId == 0x0 ? customDisplayName : ""); return SetActorNamePacket.BuildPacket(actorId, customDisplayName != null ? 0 : displayNameId, displayNameId == 0xFFFFFFFF | displayNameId == 0x0 | customDisplayName != null ? customDisplayName : "");
} }
public SubPacket CreateSpeedPacket() public SubPacket CreateSpeedPacket()

View file

@ -0,0 +1,31 @@
using FFXIVClassic_Map_Server.actors.chara.player;
using FFXIVClassic_Map_Server.Actors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.chara.npc
{
class Retainer : Npc
{
public Retainer(uint id, string retainerName, ActorClass actorClass, Player player, float posX, float posY, float posZ, float rot)
: base(0, actorClass, String.Format("_rtnre{0:x7}", id), player.GetZone(), posX, posY, posZ, rot, 0, 0, retainerName)
{
this.actorId = 0xD0000000 | id;
}
public void SendBazaarItems(Player player)
{
Inventory bazaar = new Inventory(this, 4, Inventory.RETAINER_BAZAAR);
bazaar.SendFullInventory(player);
}
public void SendStorageItems(Player player)
{
Inventory storage = new Inventory(this, 4, 1);
storage.SendFullInventory(player);
}
}
}

View file

@ -12,9 +12,11 @@ namespace FFXIVClassic_Map_Server.actors.chara.player
class Inventory class Inventory
{ {
public const ushort NORMAL = 0x0000; //Max 0xC8 public const ushort NORMAL = 0x0000; //Max 0xC8
public const ushort TRADE = 0x0001; //Max 0x96
public const ushort LOOT = 0x0004; //Max 0xA public const ushort LOOT = 0x0004; //Max 0xA
public const ushort MELDREQUEST = 0x0005; //Max 0x04 public const ushort MELDREQUEST = 0x0005; //Max 0x04
public const ushort BAZAAR = 0x0007; //Max 0x0A public const ushort BAZAAR = 0x0007; //Max 0x0A
public const ushort RETAINER_BAZAAR = 0x0008; //????
public const ushort CURRENCY = 0x0063; //Max 0x140 public const ushort CURRENCY = 0x0063; //Max 0x140
public const ushort KEYITEMS = 0x0064; //Max 0x500 public const ushort KEYITEMS = 0x0064; //Max 0x500
public const ushort EQUIPMENT = 0x00FE; //Max 0x23 public const ushort EQUIPMENT = 0x00FE; //Max 0x23

View file

@ -20,6 +20,7 @@ using FFXIVClassic_Map_Server.packets.send.actor.inventory;
using FFXIVClassic_Map_Server.actors.group; using FFXIVClassic_Map_Server.actors.group;
using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group; using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
using FFXIVClassic_Map_Server.actors.chara.npc;
namespace FFXIVClassic_Map_Server.Actors namespace FFXIVClassic_Map_Server.Actors
{ {
@ -134,6 +135,10 @@ namespace FFXIVClassic_Map_Server.Actors
public uint homepoint = 0; public uint homepoint = 0;
public byte homepointInn = 0; public byte homepointInn = 0;
//Instancing
public Retainer currentSpawnedRetainer = null;
public bool sentRetainerSpawn = false;
private List<Director> ownedDirectors = new List<Director>(); private List<Director> ownedDirectors = new List<Director>();
private Director loginInitDirector = null; private Director loginInitDirector = null;
@ -1558,6 +1563,12 @@ namespace FFXIVClassic_Map_Server.Actors
QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId)); QueuePacket(InventoryEndChangePacket.BuildPacket(toBeExamined.actorId));
} }
public void SendMyTradeToPlayer(Player player)
{
Inventory tradeInventory = new Inventory(this, 4, Inventory.TRADE);
tradeInventory.SendFullInventory(player);
}
public void SendDataPacket(params object[] parameters) public void SendDataPacket(params object[] parameters)
{ {
List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters); List<LuaParam> lParams = LuaUtils.CreateLuaParamList(parameters);
@ -1730,5 +1741,40 @@ namespace FFXIVClassic_Map_Server.Actors
Database.ChangePlayerChocoboAppearance(this, appearanceId); Database.ChangePlayerChocoboAppearance(this, appearanceId);
chocoboAppearance = appearanceId; chocoboAppearance = appearanceId;
} }
public bool SpawnMyRetainer(Npc bell, int retainerIndex)
{
Tuple<uint, uint, string> retainerData = Database.GetRetainer(this, retainerIndex);
ActorClass actorClass = Server.GetWorldManager().GetActorClass(retainerData.Item2);
if (actorClass == null)
return false;
float distance = (float)Math.Sqrt(((positionX - bell.positionX) * (positionX - bell.positionX)) + ((positionZ - bell.positionZ) * (positionZ - bell.positionZ)));
float posX = bell.positionX - ((-1.0f * (bell.positionX - positionX)) / distance);
float posZ = bell.positionZ - ((-1.0f * (bell.positionZ - positionZ)) / distance);
Retainer retainer = new Retainer(retainerData.Item1, retainerData.Item3, actorClass, this, posX, bell.positionY, positionZ, (float)Math.Atan2(positionX - posX, positionZ - posZ));
retainer.LoadEventConditions(actorClass.eventConditions);
//RetainerMeetingRelationGroup group = new RetainerMeetingRelationGroup(5555, this, retainer);
//group.SendGroupPackets(playerSession);
currentSpawnedRetainer = retainer;
sentRetainerSpawn = false;
return true;
}
public void DespawnMyRetainer()
{
if (currentSpawnedRetainer != null)
{
currentSpawnedRetainer = null;
}
}
} }
} }

View file

@ -91,7 +91,7 @@ namespace FFXIVClassic_Map_Server.actors.group
groupWork.addByte(Utils.MurmurHash2("contentGroupWork.property[0]", 0), 1); groupWork.addByte(Utils.MurmurHash2("contentGroupWork.property[0]", 0), 1);
groupWork.setTarget("/_init"); groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id, session.id); SubPacket test = groupWork.buildPacket(session.id);
test.DebugPrintSubPacket(); test.DebugPrintSubPacket();
session.QueuePacket(test); session.QueuePacket(test);
} }

View file

@ -50,7 +50,7 @@ namespace FFXIVClassic_Map_Server.actors.group
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex); SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex);
groupWork.setTarget("/_init"); groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id, session.id); SubPacket test = groupWork.buildPacket(session.id);
session.QueuePacket(test); session.QueuePacket(test);
} }

View file

@ -68,7 +68,7 @@ namespace FFXIVClassic_Map_Server.actors.group
groupWork.addProperty(this, "work._globalTemp.variableCommand"); groupWork.addProperty(this, "work._globalTemp.variableCommand");
groupWork.setTarget("/_init"); groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id, session.id); SubPacket test = groupWork.buildPacket(session.id);
test.DebugPrintSubPacket(); test.DebugPrintSubPacket();
session.QueuePacket(test); session.QueuePacket(test);
} }

View file

@ -0,0 +1,58 @@
using FFXIVClassic.Common;
using FFXIVClassic_Map_Server.actors.chara.npc;
using FFXIVClassic_Map_Server.Actors;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.packets.send.group;
using FFXIVClassic_Map_Server.packets.send.groups;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.actors.group
{
class RetainerMeetingRelationGroup : Group
{
Player player;
Retainer retainer;
public RetainerMeetingRelationGroup(ulong groupIndex, Player player, Retainer retainer)
: base(groupIndex)
{
this.player = player;
this.retainer = retainer;
}
public override int GetMemberCount()
{
return 2;
}
public override List<GroupMember> BuildMemberList(uint id)
{
List<GroupMember> groupMembers = new List<GroupMember>();
groupMembers.Add(new GroupMember(player.actorId, -1, 0x83, false, true, player.customDisplayName));
groupMembers.Add(new GroupMember(retainer.actorId, -1, 0x83, false, true, retainer.customDisplayName));
return groupMembers;
}
public override uint GetTypeId()
{
return 50003;
}
public override void SendInitWorkValues(Session session)
{
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex);
groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.id);
test.DebugPrintSubPacket();
session.QueuePacket(test);
}
}
}

View file

@ -9,6 +9,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using FFXIVClassic_Map_Server.actors.chara.npc;
namespace FFXIVClassic_Map_Server.dataobjects namespace FFXIVClassic_Map_Server.dataobjects
{ {
@ -96,11 +97,28 @@ namespace FFXIVClassic_Map_Server.dataobjects
//Remove missing actors //Remove missing actors
for (int i = 0; i < actorInstanceList.Count; i++) for (int i = 0; i < actorInstanceList.Count; i++)
{ {
if (!list.Contains(actorInstanceList[i])) //Retainer Instance
if (actorInstanceList[i] is Retainer && playerActor.currentSpawnedRetainer == null)
{ {
QueuePacket(RemoveActorPacket.BuildPacket(actorInstanceList[i].actorId)); QueuePacket(RemoveActorPacket.BuildPacket(actorInstanceList[i].actorId));
actorInstanceList.RemoveAt(i); actorInstanceList.RemoveAt(i);
} }
else if (!list.Contains(actorInstanceList[i]) && !(actorInstanceList[i] is Retainer))
{
QueuePacket(RemoveActorPacket.BuildPacket(actorInstanceList[i].actorId));
actorInstanceList.RemoveAt(i);
}
}
//Retainer Instance
if (playerActor.currentSpawnedRetainer != null && !playerActor.sentRetainerSpawn)
{
Actor actor = playerActor.currentSpawnedRetainer;
QueuePacket(actor.GetSpawnPackets(playerActor, 1));
QueuePacket(actor.GetInitPackets());
QueuePacket(actor.GetSetEventStatusPackets());
actorInstanceList.Add(actor);
playerActor.sentRetainerSpawn = true;
} }
//Add new actors or move //Add new actors or move

View file

@ -194,7 +194,7 @@ namespace FFXIVClassic_Map_Server.packets.send.groups
} }
public SubPacket buildPacket(uint playerActorID, uint actorID) public SubPacket buildPacket(uint actorID)
{ {
binWriter.Seek(0x8, SeekOrigin.Begin); binWriter.Seek(0x8, SeekOrigin.Begin);
binWriter.Write((byte)runningByteTotal); binWriter.Write((byte)runningByteTotal);

View file

@ -12,6 +12,7 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
public const uint GroupInvitationRelationGroup = 50001; public const uint GroupInvitationRelationGroup = 50001;
public const uint TradeRelationGroup = 50002; public const uint TradeRelationGroup = 50002;
public const uint RetainerMeetingRelationGroup = 50003;
public const uint BazaarBuyItemRelationGroup = 50009; public const uint BazaarBuyItemRelationGroup = 50009;
public const uint RetainerGroup = 80001; public const uint RetainerGroup = 80001;

View file

@ -0,0 +1,36 @@
using FFXIVClassic.Common;
using FFXIVClassic_World_Server.Actor.Group.Work;
using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_World_Server.DataObjects.Group
{
class RetainerMeetingRelationGroup : Relation
{
public RetainerMeetingRelationGroup(ulong groupIndex, uint host, uint other, uint command, ulong topicGroup)
: base(groupIndex, host, other, command, topicGroup)
{
}
public override uint GetTypeId()
{
return Group.RetainerMeetingRelationGroup;
}
public override void SendInitWorkValues(Session session)
{
SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupIndex);
groupWork.setTarget("/_init");
SubPacket test = groupWork.buildPacket(session.sessionId);
test.DebugPrintSubPacket();
session.clientConnection.QueuePacket(test);
}
}
}

View file

@ -165,7 +165,7 @@ namespace FFXIVClassic_World_Server
try try
{ {
conn.Open(); conn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT id, name, classActorId, cdIDOffset, placeName, conditions, level FROM server_retainers INNER JOIN characters_retainers ON retainerId = server_retainers.id WHERE characterId = @charaId", conn); MySqlCommand cmd = new MySqlCommand("SELECT id, name, actorClassId, cdIDOffset, placeName, conditions, level FROM server_retainers INNER JOIN characters_retainers ON retainerId = server_retainers.id WHERE characterId = @charaId", conn);
cmd.Parameters.AddWithValue("@charaId", charaId); cmd.Parameters.AddWithValue("@charaId", charaId);
using (MySqlDataReader Reader = cmd.ExecuteReader()) using (MySqlDataReader Reader = cmd.ExecuteReader())
{ {
@ -173,13 +173,13 @@ namespace FFXIVClassic_World_Server
{ {
uint id = Reader.GetUInt32("id") | 0xE0000000; uint id = Reader.GetUInt32("id") | 0xE0000000;
string name = Reader.GetString("name"); string name = Reader.GetString("name");
uint classActorId = Reader.GetUInt32("classActorId"); uint actorClassId = Reader.GetUInt32("actorClassId");
byte cdIDOffset = Reader.GetByte("cdIDOffset"); byte cdIDOffset = Reader.GetByte("cdIDOffset");
ushort placeName = Reader.GetUInt16("placeName"); ushort placeName = Reader.GetUInt16("placeName");
byte conditions = Reader.GetByte("conditions"); byte conditions = Reader.GetByte("conditions");
byte level = Reader.GetByte("level"); byte level = Reader.GetByte("level");
members.Add(new RetainerGroupMember(id, name, classActorId, cdIDOffset, placeName, conditions, level)); members.Add(new RetainerGroupMember(id, name, actorClassId, cdIDOffset, placeName, conditions, level));
} }
} }
} }

View file

@ -95,6 +95,7 @@
<Compile Include="DataObjects\Group\Linkshell.cs" /> <Compile Include="DataObjects\Group\Linkshell.cs" />
<Compile Include="DataObjects\Group\LinkshellMember.cs" /> <Compile Include="DataObjects\Group\LinkshellMember.cs" />
<Compile Include="DataObjects\Group\Party.cs" /> <Compile Include="DataObjects\Group\Party.cs" />
<Compile Include="DataObjects\Group\RetainerMeetingRelationGroup.cs" />
<Compile Include="DataObjects\Group\Relation.cs" /> <Compile Include="DataObjects\Group\Relation.cs" />
<Compile Include="DataObjects\Group\RetainerGroup.cs" /> <Compile Include="DataObjects\Group\RetainerGroup.cs" />
<Compile Include="DataObjects\Group\RetainerGroupMember.cs" /> <Compile Include="DataObjects\Group\RetainerGroupMember.cs" />
@ -190,7 +191,8 @@
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent></PostBuildEvent> <PostBuildEvent>
</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -217,6 +217,7 @@ namespace FFXIVClassic_World_Server
SendPartySync(pt); SendPartySync(pt);
mRetainerGroupManager.GetRetainerGroup(session.sessionId).SendGroupPackets(session); mRetainerGroupManager.GetRetainerGroup(session.sessionId).SendGroupPackets(session);
List<Linkshell> linkshells = mLinkshellManager.GetPlayerLinkshellMembership(session.sessionId); List<Linkshell> linkshells = mLinkshellManager.GetPlayerLinkshellMembership(session.sessionId);
foreach (Linkshell ls in linkshells) foreach (Linkshell ls in linkshells)
ls.SendGroupPackets(session); ls.SendGroupPackets(session);

View file

@ -7,14 +7,14 @@ Functions:
eventPushStepOpenRetainerMenu() - Opens menu to choose retainer eventPushStepOpenRetainerMenu() - Opens menu to choose retainer
eventRingBell() - Plays the bell ring animation eventRingBell() - Plays the bell ring animation
eventPushRetainerCallCaution() - Shows warning that a open bazaar will be closed if retainer chosen eventPushRetainerCallCaution() - Shows warning that a open bazaar will be closed if retainer chosen
eventTalkRetainerMenu(?, ?) - Opens retainer menu eventTalkRetainerMenu(hasPossessions, showDispatchChoice) - Opens retainer menu.
eventTalkRetainerDismissal(?) eventTalkRetainerDismissal(hasPossessions) - Show dismiss confirmation.
eventTalkRetainerMannequin(?) eventTalkRetainerMannequin(0:Enable/1:Disable) - Shows dialog to enable/disable modeling.
eventTalkRetainerItemTrade(?) eventTalkRetainerItemTrade(?) - ??Opens retainer storage??
eventTalkRetainerItemList(?) eventTalkRetainerItemList(?) - ??Opens bazaar??
eventTalkSelectBazaarStreet(?) eventReturnResult(?, ?) - ??Trade related??
eventReturnResult(?, ?) eventTalkSelectBazaarStreet(limitsWardChoices) - Shows the dialog to send a retainer to a street. Set to 20.
eventTalkFinish() eventTalkFinish() - Finishs the talk with retainer
eventPlayerTurn(rotation) - Turns the player eventPlayerTurn(rotation) - Turns the player
--]] --]]
@ -25,8 +25,8 @@ function init(npc)
end end
function onEventStarted(player, npc, triggerName) function onEventStarted(player, npc, triggerName)
retainerNumber = callClientFunction(player, "eventPushStepOpenRetainerMenu"); retainerNumber = callClientFunction(player, "eventPushRetainerCallCaution", true, false);
callClientFunction(player, "eventRingBell"); --player:SpawnMyRetainer(npc, retainerNumber);
callClientFunction(player, "eventTalkRetainerMenu"); --callClientFunction(player, "eventRingBell");
player:EndEvent(); player:EndEvent();
end end

View file

@ -0,0 +1,31 @@
--[[
OrdinaryRetainer Script
Functions:
eventTalkRetainerOther() -
eventTalkRetainerMenu(mode, hasPossessions) - Opens the main menu. If mode == 2, hide dismiss option.
eventTalkRetainerDismissal(hasPossessions) - Show dismiss confirmation.
eventTalkRetainerMannequin(0:enable/1:disable confirm) - Show bazaar modeling confirmation.
eventTalkRetainerItemTrade(?) - ??Opens retainer storage??
eventTalkRetainerItemList(?) - ??Opens bazaar??
eventReturnResult(?, ?) - ??Trade related??
sayToPlayer(actorClassId, messageType, argument) - Makes the retainer say a phrase to the player.
eventTalkFinish() - Stops npc from looking at player.
eventPlayerTurn(angle) - Turns player to angle.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "eventTalkRetainerItemList", 1);
--callClientFunction(player, "eventTalkRetainerDismissal", 0, false);
player:EndEvent();
end