1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-21 04:07:48 +00:00

Fixed actors not being resent on login into already available session due to those actors being in the instance list but not the client. Added chocobo rental code.

This commit is contained in:
Filip Maj 2019-07-11 12:13:23 -04:00
parent d3027c3b26
commit 8687e43191
5 changed files with 117 additions and 22 deletions

View file

@ -130,9 +130,11 @@ namespace Meteor.Map.Actors
//Mount Related //Mount Related
public bool hasChocobo; public bool hasChocobo;
public bool hasGoobbue; public bool hasGoobbue;
public byte chocoboAppearance;
public string chocoboName; public string chocoboName;
public byte mountState = 0; public byte mountState = 0;
public byte chocoboAppearance;
public uint rentalExpireTime = 0;
public byte rentalMinLeft = 0;
public uint achievementPoints; public uint achievementPoints;
@ -370,7 +372,7 @@ namespace Meteor.Map.Actors
} }
if (mountState == 1) if (mountState == 1)
subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance)); subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft));
else if (mountState == 2) else if (mountState == 2)
subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1)); subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1));
@ -554,7 +556,8 @@ namespace Meteor.Map.Actors
{ {
QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false)); QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false));
QueuePacket(SetDalamudPacket.BuildPacket(actorId, 0)); QueuePacket(SetDalamudPacket.BuildPacket(actorId, 0));
QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, 0x01)); if (spawnType != 0x13 && spawnType != 0x14)
QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, 0x01));
QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1)); QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1));
QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId)); QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
@ -840,7 +843,7 @@ namespace Meteor.Map.Actors
public void SendMountAppearance() public void SendMountAppearance()
{ {
if (mountState == 1) if (mountState == 1)
BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance), true); BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft), true);
else if (mountState == 2) else if (mountState == 2)
BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true); BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true);
} }
@ -1914,6 +1917,17 @@ namespace Meteor.Map.Actors
chocoboAppearance = appearanceId; chocoboAppearance = appearanceId;
} }
public void StartChocoboRental(byte numMins)
{
rentalExpireTime = Utils.UnixTimeStampUTC() + ((uint)numMins * 60);
rentalMinLeft = numMins;
}
public bool IsChocoboRentalActive()
{
return rentalExpireTime != 0;
}
public Retainer SpawnMyRetainer(Npc bell, int retainerIndex) public Retainer SpawnMyRetainer(Npc bell, int retainerIndex)
{ {
Retainer retainer = Database.LoadRetainer(this, retainerIndex); Retainer retainer = Database.LoadRetainer(this, retainerIndex);
@ -1948,15 +1962,37 @@ namespace Meteor.Map.Actors
public override void Update(DateTime tick) public override void Update(DateTime tick)
{ {
// Chocobo Rental Expirey
if (rentalExpireTime != 0)
{
uint tickUTC = Utils.UnixTimeStampUTC(tick);
//Rental has expired, dismount
if (rentalExpireTime <= tickUTC)
{
rentalExpireTime = 0;
rentalMinLeft = 0;
ChangeMusic(GetZone().bgmDay);
SetMountState(0);
ChangeSpeed(0.0f, 2.0f, 5.0f, 5.0f);
ChangeState(0);
}
else
{
rentalMinLeft = (byte) ((rentalExpireTime - tickUTC) /60);
}
}
aiContainer.Update(tick); aiContainer.Update(tick);
statusEffects.Update(tick); statusEffects.Update(tick);
} }
public override void PostUpdate(DateTime tick, List<SubPacket> packets = null) public override void PostUpdate(DateTime tick, List<SubPacket> packets = null)
{ {
// todo: is this correct? // todo: is this correct?
if (this.playerSession.isUpdatesLocked) if (this.playerSession.isUpdatesLocked)
return; return;
// todo: should probably add another flag for battleTemp since all this uses reflection // todo: should probably add another flag for battleTemp since all this uses reflection
packets = new List<SubPacket>(); packets = new List<SubPacket>();
@ -2005,8 +2041,7 @@ namespace Meteor.Map.Actors
updateFlags ^= ActorUpdateFlags.Hotbar; updateFlags ^= ActorUpdateFlags.Hotbar;
} }
base.PostUpdate(tick, packets); base.PostUpdate(tick, packets);
} }

View file

@ -19,6 +19,9 @@ along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
=========================================================================== ===========================================================================
*/ */
using System;
using System.IO;
using Meteor.Common; using Meteor.Common;
namespace Meteor.Map.packets.send.player namespace Meteor.Map.packets.send.player
@ -45,10 +48,18 @@ namespace Meteor.Map.packets.send.player
public const ushort OPCODE = 0x0197; public const ushort OPCODE = 0x0197;
public const uint PACKET_SIZE = 0x28; public const uint PACKET_SIZE = 0x28;
public static SubPacket BuildPacket(uint sourceActorId, int appearanceId) public static SubPacket BuildPacket(uint sourceActorId, byte chocoboAppearance, uint rentalExpireTime, byte rentalMinLeft)
{ {
byte[] data = new byte[PACKET_SIZE - 0x20]; byte[] data = new byte[PACKET_SIZE - 0x20];
data[5] = (byte)(appearanceId & 0xFF); using (MemoryStream mem = new MemoryStream(data))
{
using (BinaryWriter binWriter = new BinaryWriter(mem))
{
binWriter.Write((UInt32)rentalExpireTime);
binWriter.Write((Byte)rentalMinLeft);
binWriter.Write((Byte)chocoboAppearance);
}
}
return new SubPacket(OPCODE, sourceActorId, data); return new SubPacket(OPCODE, sourceActorId, data);
} }
} }

View file

@ -124,7 +124,10 @@ namespace Meteor.Map
public Session AddSession(uint id) public Session AddSession(uint id)
{ {
if (mSessionList.ContainsKey(id)) if (mSessionList.ContainsKey(id))
{
mSessionList[id].ClearInstance();
return mSessionList[id]; return mSessionList[id];
}
Session session = new Session(id); Session session = new Session(id);
mSessionList.Add(id, session); mSessionList.Add(id, session);

View file

@ -130,9 +130,11 @@ namespace Meteor.Map.Actors
//Mount Related //Mount Related
public bool hasChocobo; public bool hasChocobo;
public bool hasGoobbue; public bool hasGoobbue;
public byte chocoboAppearance;
public string chocoboName; public string chocoboName;
public byte mountState = 0; public byte mountState = 0;
public byte chocoboAppearance;
public uint rentalExpireTime = 0;
public byte rentalMinLeft = 0;
public uint achievementPoints; public uint achievementPoints;
@ -370,7 +372,7 @@ namespace Meteor.Map.Actors
} }
if (mountState == 1) if (mountState == 1)
subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance)); subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft));
else if (mountState == 2) else if (mountState == 2)
subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1)); subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1));
@ -554,7 +556,8 @@ namespace Meteor.Map.Actors
{ {
QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false)); QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false));
QueuePacket(SetDalamudPacket.BuildPacket(actorId, 0)); QueuePacket(SetDalamudPacket.BuildPacket(actorId, 0));
QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, 0x01)); if (spawnType != 0x13 && spawnType != 0x14)
QueuePacket(SetMusicPacket.BuildPacket(actorId, zone.bgmDay, 0x01));
QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1)); QueuePacket(SetWeatherPacket.BuildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR, 1));
QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId)); QueuePacket(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
@ -840,7 +843,7 @@ namespace Meteor.Map.Actors
public void SendMountAppearance() public void SendMountAppearance()
{ {
if (mountState == 1) if (mountState == 1)
BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance), true); BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft), true);
else if (mountState == 2) else if (mountState == 2)
BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true); BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true);
} }
@ -1914,6 +1917,17 @@ namespace Meteor.Map.Actors
chocoboAppearance = appearanceId; chocoboAppearance = appearanceId;
} }
public void StartChocoboRental(byte numMins)
{
rentalExpireTime = Utils.UnixTimeStampUTC() + ((uint)numMins * 60);
rentalMinLeft = numMins;
}
public bool IsChocoboRentalActive()
{
return rentalExpireTime != 0;
}
public Retainer SpawnMyRetainer(Npc bell, int retainerIndex) public Retainer SpawnMyRetainer(Npc bell, int retainerIndex)
{ {
Retainer retainer = Database.LoadRetainer(this, retainerIndex); Retainer retainer = Database.LoadRetainer(this, retainerIndex);
@ -1948,15 +1962,37 @@ namespace Meteor.Map.Actors
public override void Update(DateTime tick) public override void Update(DateTime tick)
{ {
// Chocobo Rental Expirey
if (rentalExpireTime != 0)
{
uint tickUTC = Utils.UnixTimeStampUTC(tick);
//Rental has expired, dismount
if (rentalExpireTime <= tickUTC)
{
rentalExpireTime = 0;
rentalMinLeft = 0;
ChangeMusic(GetZone().bgmDay);
SetMountState(0);
ChangeSpeed(0.0f, 2.0f, 5.0f, 5.0f);
ChangeState(0);
}
else
{
rentalMinLeft = (byte) ((rentalExpireTime - tickUTC) /60);
}
}
aiContainer.Update(tick); aiContainer.Update(tick);
statusEffects.Update(tick); statusEffects.Update(tick);
} }
public override void PostUpdate(DateTime tick, List<SubPacket> packets = null) public override void PostUpdate(DateTime tick, List<SubPacket> packets = null)
{ {
// todo: is this correct? // todo: is this correct?
if (this.playerSession.isUpdatesLocked) if (this.playerSession.isUpdatesLocked)
return; return;
// todo: should probably add another flag for battleTemp since all this uses reflection // todo: should probably add another flag for battleTemp since all this uses reflection
packets = new List<SubPacket>(); packets = new List<SubPacket>();
@ -2005,8 +2041,7 @@ namespace Meteor.Map.Actors
updateFlags ^= ActorUpdateFlags.Hotbar; updateFlags ^= ActorUpdateFlags.Hotbar;
} }
base.PostUpdate(tick, packets); base.PostUpdate(tick, packets);
} }

View file

@ -19,6 +19,9 @@ along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
=========================================================================== ===========================================================================
*/ */
using System;
using System.IO;
using Meteor.Common; using Meteor.Common;
namespace Meteor.Map.packets.send.player namespace Meteor.Map.packets.send.player
@ -45,10 +48,18 @@ namespace Meteor.Map.packets.send.player
public const ushort OPCODE = 0x0197; public const ushort OPCODE = 0x0197;
public const uint PACKET_SIZE = 0x28; public const uint PACKET_SIZE = 0x28;
public static SubPacket BuildPacket(uint sourceActorId, int appearanceId) public static SubPacket BuildPacket(uint sourceActorId, byte chocoboAppearance, uint rentalExpireTime, byte rentalMinLeft)
{ {
byte[] data = new byte[PACKET_SIZE - 0x20]; byte[] data = new byte[PACKET_SIZE - 0x20];
data[5] = (byte)(appearanceId & 0xFF); using (MemoryStream mem = new MemoryStream(data))
{
using (BinaryWriter binWriter = new BinaryWriter(mem))
{
binWriter.Write((UInt32)rentalExpireTime);
binWriter.Write((Byte)rentalMinLeft);
binWriter.Write((Byte)chocoboAppearance);
}
}
return new SubPacket(OPCODE, sourceActorId, data); return new SubPacket(OPCODE, sourceActorId, data);
} }
} }