Skip to content
This repository has been archived by the owner on Mar 5, 2021. It is now read-only.

Learnt spells and talents, faction and action buttons handling #17

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
40 changes: 40 additions & 0 deletions Database/Updates/KnownSpellsTalents.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
SET FOREIGN_KEY_CHECKS=0;

-- -----------------------------------------------------
-- Table `knownspells`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `knownspells`;
CREATE TABLE `knownspells` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`spell` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
`guid` INT(11) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
INDEX `fk_knownspells_characters1_idx` (`guid` ASC),
CONSTRAINT `fk_knownspells_characters1`
FOREIGN KEY (`guid`)
REFERENCES `characters` (`guid`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4;


-- -----------------------------------------------------
-- Table `knowntalents`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `knowntalents`;
CREATE TABLE `knowntalents` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`talent` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
`guid` INT(11) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
INDEX `fk_knowntalents_characters1_idx` (`guid` ASC),
CONSTRAINT `fk_knowntalents_characters1`
FOREIGN KEY (`guid`)
REFERENCES `characters` (`guid`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8mb4;

SET FOREIGN_KEY_CHECKS=1;
60 changes: 59 additions & 1 deletion WorldServer/Game/Objects/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,39 @@ private void SetStartProfiencies()

foreach (ushort spell in spellinfo)
this.Spells.Add(spell, new PlayerSpell(spell));

//Known Spells/Talents
var knownspells = Database.KnownSpells.Values
.Where(x => x.Player == Guid)
.Select(x => x.SpellID);

foreach (ushort spell in knownspells)
this.Spells.Add(spell, new PlayerSpell(spell));

var knowntalent = Database.KnownTalents.Values
.Where(x => x.Player == Guid)
.Select(x => x.TalentID);

foreach (ushort spell in knowntalent)
this.Spells.Add(spell, new PlayerSpell(spell));

}

public void ActionButtonsInitalize()
{
PacketWriter pkt = new PacketWriter(Opcodes.SMSG_ACTION_BUTTONS);

for (var button = 0; button < 119; button++) // 119 'or 480 ?
{
var ActionBarInit = Database.CreateActionButtons.Values.Find(x => x.Button == button);

if (ActionBarInit != null)
pkt.WriteUInt32((uint)ActionBarInit.Action | ((uint)ActionBarInit.Type << 24));
else
pkt.WriteUInt32(0);

this.Client.Send(pkt);
}
}

public void SendInitialSpells()
Expand All @@ -516,6 +549,29 @@ public void SendInitialSpells()
this.Client.Send(pkt);
}

//Basic Factions
public void SendInitalizeFactions()
{
const int count = 0x40;
PacketWriter pkt = new PacketWriter(Opcodes.SMSG_INITIALIZE_FACTIONS);
pkt.WriteUInt32(count);
//var rep = reps[(FactionReputationIndex);
pkt.WriteUInt16((byte)2); //rep.flags
pkt.WriteUInt16(0); //rep.value
this.Client.Send(pkt);
}

public void SendReputationStandingUpdate()
{
PacketWriter pkt = new PacketWriter(Opcodes.SMSG_SET_FACTION_STANDING);
pkt.WriteUInt32((byte)1);
pkt.WriteUInt16(0); // count (we only ever send 1)
pkt.WriteUInt16(0); //rep index
pkt.WriteUInt16(0); //rep.value

this.Client.Send(pkt);
}

#endregion

#region Visualisation Functions
Expand Down Expand Up @@ -599,7 +655,9 @@ public void ToggleChatFlag(ChatFlags flag)
public void AddActionButton(byte button, ushort action, byte type, byte misc)
{
ActionButton ab = new ActionButton(action, misc, type);
this.ActionButtons.Add(button, ab);

if (this.ActionButtons.ContainsKey(button))
this.ActionButtons.Add(button, ab);
}

public void RemoveActionButton(byte button)
Expand Down
5 changes: 3 additions & 2 deletions WorldServer/Game/Objects/UnitExtensions/SpellExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,14 @@ public static SpellCheckCastResult PrepareSpell(this Unit u, SpellCast spell)
u.ChannelObject = spell.Targets.Target.Guid;
GridManager.Instance.SendSurrounding(u.BuildUpdate(), u);

if (u.IsTypeOf(ObjectTypes.TYPE_PLAYER))
//Temp Disable Channel
/*if (u.IsTypeOf(ObjectTypes.TYPE_PLAYER))
{
PacketWriter channel = new PacketWriter(Opcodes.MSG_CHANNEL_START);
channel.WriteUInt32(spell.Spell.Id);
channel.WriteInt32(spell.Duration * 1000);
((Player)u).Client.Send(channel);
}
}*/
}
return SpellCheckCastResult.SPELL_CAST_OK;
}
Expand Down
26 changes: 26 additions & 0 deletions WorldServer/Game/Structs/PlayerStructs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,32 @@ public class LevelStatsInfo
public uint Spi { get; set; }
}

[Table("knownspells")]
public class KnownSpells
{
[Key]
[Column("id")]
public uint Id { get; set; }
[Column("guid")]
public ulong Player { get; set; }

[Column("spell")]
public ushort SpellID { get; set; }
}

[Table("knowntalents")]
public class KnownTalents
{
[Key]
[Column("id")]
public uint Id { get; set; }
[Column("guid")]
public ulong Player { get; set; }

[Column("talent")]
public ushort TalentID { get; set; }
}

[Table("player_classlevelstats")]
public class ClassLevelStat
{
Expand Down
21 changes: 21 additions & 0 deletions WorldServer/Packets/Handlers/CharHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using WorldServer.Game.Objects.UnitExtensions;
using WorldServer.Network;
using WorldServer.Storage;
using Common.Logging;

namespace WorldServer.Packets.Handlers
{
Expand Down Expand Up @@ -240,15 +241,35 @@ public static void HandleRepopRequest(ref PacketReader packet, ref WorldManager

public static void HandleSetActionButtonOpcode(ref PacketReader packet, ref WorldManager manager)
{
Log.Message(LogType.DEBUG, "WORLD: Received opcode CMSG_SET_ACTION_BUTTON!");
byte button = packet.ReadUInt8();
ushort action = packet.ReadUInt16();
byte misc = packet.ReadUInt8();
byte type = packet.ReadUInt8();

Log.Message(LogType.DEBUG, "BUTTON: {0} ACTION: {1} TYPE: {2}!", button, action, type);
if (action == 0)
{
Log.Message(LogType.DEBUG, "MISC: Remove action from button {0}", button);
manager.Character.RemoveActionButton(button);
}
else
{
switch (type)
{
case (byte)ActionButtonTypes.ACTION_BUTTON_SPELL:
Log.Message(LogType.DEBUG, "MISC: Added Spell {0} into button {1}", action, button);
break;
case (byte)ActionButtonTypes.ACTION_BUTTON_ITEM:
Log.Message(LogType.DEBUG, "MISC: Added Item {0} into button {1}", action, button);
break;
default:
Log.Message(LogType.ERROR, "MISC: Unknown action button type {0} for action %u into button {1}", action, button);
return;
}

manager.Character.AddActionButton(button, action, type, misc);
}
}
}
}
44 changes: 41 additions & 3 deletions WorldServer/Packets/Handlers/NPCHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
using WorldServer.Game.Structs;
using WorldServer.Network;
using WorldServer.Storage;
using System;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
using Common.Database;

namespace WorldServer.Packets.Handlers
{
Expand Down Expand Up @@ -250,6 +254,10 @@ public static void HandleTrainerBuySpellOpcode(ref PacketReader packet, ref Worl
ulong guid = packet.ReadUInt64();
uint spellID = packet.ReadUInt32();

PacketWriter pkt = new PacketWriter(Opcodes.SMSG_LEARNED_SPELL);
pkt.WriteUInt32((ushort)spellID);
manager.Send(pkt);

Spell spell = null;
if (!DBC.Spell.TryGetValue(spellID, out spell)) //Only use those with spells
return;
Expand All @@ -271,19 +279,33 @@ public static void HandleTrainerBuySpellOpcode(ref PacketReader packet, ref Worl
player.Talents.Add(ability.m_ID);
player.TalentPoints -= 10;

//TODO ADD SPELL TO SPELLBOOK

player.SendBuySpellSucceed(guid, spellID);
manager.Character.Dirty = true;
player.SendPlaySpellVisual(guid, 0xB3);

player.Spells.Add(spellID, new PlayerSpell(spell));
//player.Spells.Add(spellID, new PlayerSpell(spell)); //TODO : Check why crash server after adding talents from here

Console.WriteLine("Learn Talent Guid: " + player.Guid);
Console.WriteLine("Learn Talent ID: " + spellID);
}

break;
}

player.SendTalentList();

List<string> columns = new List<string>{
"guid", "talent"
};

List<MySqlParameter> parameters = new List<MySqlParameter>
{
new MySqlParameter("@guid", player.Guid),
new MySqlParameter("@talent", spellID),
};

BaseContext.SaveEntity("knowntalents", columns, parameters, Globals.CONNECTION_STRING);
Database.KnownTalents.Reload();
}
else if (Database.Creatures.ContainsKey(guid)) //NPC Spell purchase
{
Expand All @@ -307,6 +329,22 @@ public static void HandleTrainerBuySpellOpcode(ref PacketReader packet, ref Worl
player.Spells.Add(spellID, new PlayerSpell(spell));

creature.SendSpellList(player);

Console.WriteLine("Learn Player Guid: " + player.Guid);
Console.WriteLine("Learn Spell ID: " + spellID);
// TODO: 2 spells with same id crash server
List<string> columns = new List<string>{
"guid", "spell"
};

List<MySqlParameter> parameters = new List<MySqlParameter>
{
new MySqlParameter("@guid", player.Guid),
new MySqlParameter("@spell", spellID),
};

BaseContext.SaveEntity("knownspells", columns, parameters, Globals.CONNECTION_STRING);
Database.KnownSpells.Reload();
}
}

Expand Down
7 changes: 4 additions & 3 deletions WorldServer/Packets/Handlers/WorldHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ public static void HandlePlayerLogin(ref PacketReader packet, ref WorldManager m
manager.Character.IsOnline = true;

MiscHandler.HandleLoginSetTimespeed(ref manager);
/*
* SMSG_ACTION_BUTTONS
*/

manager.Character.ActionButtonsInitalize();
manager.Character.SendInitialSpells();
manager.Character.SendInitalizeFactions();
manager.Character.SendReputationStandingUpdate();
manager.Character.SendMOTD();
manager.Character.PreLoad();

Expand Down
4 changes: 4 additions & 0 deletions WorldServer/Storage/Database.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public static class Database
{
public static DbSet<uint, AreaTrigger> AreaTriggers;
public static DbSet<uint, ClassLevelStat> ClassLevelStats;
public static DbSet<uint, KnownSpells> KnownSpells;
public static DbSet<uint, KnownTalents> KnownTalents;
public static DbSet<uint, CreateActionButton> CreateActionButtons;
public static DbSet<uint, CreatePlayerInfo> CreatePlayerInfo;
public static DbSet<uint, CreateSkillInfo> CreateSkillInfo;
Expand Down Expand Up @@ -79,6 +81,8 @@ public static void Initialize()
GameObjects = new DbSet<ulong, GameObject>(true);
Items = new DbSet<ulong, Item>(true, true);
Players = new DbSet<ulong, Player>(true, true);
KnownSpells = new DbSet<uint, KnownSpells>(false, true);
KnownTalents = new DbSet<uint, KnownTalents>(false, true);
SocialList = new GroupedDbSet<ulong, List<SocialList>>(QueryDefault + "character_social", "Social Lists", true);
}

Expand Down