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
public bool hasChocobo;
public bool hasGoobbue;
public byte chocoboAppearance;
public string chocoboName;
public byte mountState = 0;
public byte chocoboAppearance;
public uint rentalExpireTime = 0;
public byte rentalMinLeft = 0;
public uint achievementPoints;
@ -370,7 +372,7 @@ namespace Meteor.Map.Actors
}
if (mountState == 1)
subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance));
subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft));
else if (mountState == 2)
subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1));
@ -554,7 +556,8 @@ namespace Meteor.Map.Actors
{
QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false));
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(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
@ -840,7 +843,7 @@ namespace Meteor.Map.Actors
public void SendMountAppearance()
{
if (mountState == 1)
BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance), true);
BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft), true);
else if (mountState == 2)
BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true);
}
@ -1914,6 +1917,17 @@ namespace Meteor.Map.Actors
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)
{
Retainer retainer = Database.LoadRetainer(this, retainerIndex);
@ -1948,6 +1962,28 @@ namespace Meteor.Map.Actors
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);
statusEffects.Update(tick);
}
@ -2006,7 +2042,6 @@ namespace Meteor.Map.Actors
updateFlags ^= ActorUpdateFlags.Hotbar;
}
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;
namespace Meteor.Map.packets.send.player
@ -45,10 +48,18 @@ namespace Meteor.Map.packets.send.player
public const ushort OPCODE = 0x0197;
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];
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);
}
}

View File

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

View File

@ -130,9 +130,11 @@ namespace Meteor.Map.Actors
//Mount Related
public bool hasChocobo;
public bool hasGoobbue;
public byte chocoboAppearance;
public string chocoboName;
public byte mountState = 0;
public byte chocoboAppearance;
public uint rentalExpireTime = 0;
public byte rentalMinLeft = 0;
public uint achievementPoints;
@ -370,7 +372,7 @@ namespace Meteor.Map.Actors
}
if (mountState == 1)
subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance));
subpackets.Add(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft));
else if (mountState == 2)
subpackets.Add(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1));
@ -554,7 +556,8 @@ namespace Meteor.Map.Actors
{
QueuePacket(SetActorIsZoningPacket.BuildPacket(actorId, false));
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(SetMapPacket.BuildPacket(actorId, zone.regionId, zone.actorId));
@ -840,7 +843,7 @@ namespace Meteor.Map.Actors
public void SendMountAppearance()
{
if (mountState == 1)
BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance), true);
BroadcastPacket(SetCurrentMountChocoboPacket.BuildPacket(actorId, chocoboAppearance, rentalExpireTime, rentalMinLeft), true);
else if (mountState == 2)
BroadcastPacket(SetCurrentMountGoobbuePacket.BuildPacket(actorId, 1), true);
}
@ -1914,6 +1917,17 @@ namespace Meteor.Map.Actors
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)
{
Retainer retainer = Database.LoadRetainer(this, retainerIndex);
@ -1948,6 +1962,28 @@ namespace Meteor.Map.Actors
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);
statusEffects.Update(tick);
}
@ -2006,7 +2042,6 @@ namespace Meteor.Map.Actors
updateFlags ^= ActorUpdateFlags.Hotbar;
}
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;
namespace Meteor.Map.packets.send.player
@ -45,10 +48,18 @@ namespace Meteor.Map.packets.send.player
public const ushort OPCODE = 0x0197;
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];
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);
}
}