Ported .Net Core commits:

hondacrx:
- Initial commit: Switch to .Net Core 2.0
- Fix build and removed not needed files
Fabi:
- Updated solution platforms.
- Changed folder structure.
- Change library target framework to netstandard2.0.
- Updated solution platforms again...
- Removed windows specific kernel32 function usage (Ctrl-C handler).
This commit is contained in:
Fabian
2017-10-26 17:23:44 +02:00
parent 227702e19c
commit a3dc7b3f48
844 changed files with 26064 additions and 1824 deletions
+240
View File
@@ -0,0 +1,240 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Framework.Database;
using Game.Entities;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Game.Spells
{
public class SkillDiscovery
{
public static void LoadSkillDiscoveryTable()
{
uint oldMSTime = Time.GetMSTime();
SkillDiscoveryStorage.Clear(); // need for reload
// 0 1 2 3
SQLResult result = DB.World.Query("SELECT spellId, reqSpell, reqSkillValue, chance FROM skill_discovery_template");
if (result.IsEmpty())
{
Log.outError(LogFilter.ServerLoading, "Loaded 0 skill discovery definitions. DB table `skill_discovery_template` is empty.");
return;
}
uint count = 0;
StringBuilder ssNonDiscoverableEntries = new StringBuilder();
List<uint> reportedReqSpells = new List<uint>();
do
{
uint spellId = result.Read<uint>(0);
int reqSkillOrSpell = result.Read<int>(1);
uint reqSkillValue = result.Read<uint>(2);
float chance = result.Read<float>(3);
if (chance <= 0) // chance
{
ssNonDiscoverableEntries.AppendFormat("spellId = {0} reqSkillOrSpell = {1} reqSkillValue = {2} chance = {3} (chance problem)\n", spellId, reqSkillOrSpell, reqSkillValue, chance);
continue;
}
if (reqSkillOrSpell > 0) // spell case
{
uint absReqSkillOrSpell = (uint)reqSkillOrSpell;
SpellInfo reqSpellInfo = Global.SpellMgr.GetSpellInfo(absReqSkillOrSpell);
if (reqSpellInfo == null)
{
if (!reportedReqSpells.Contains(absReqSkillOrSpell))
{
Log.outError(LogFilter.Sql, "Spell (ID: {0}) have not existed spell (ID: {1}) in `reqSpell` field in `skill_discovery_template` table", spellId, reqSkillOrSpell);
reportedReqSpells.Add(absReqSkillOrSpell);
}
continue;
}
// mechanic discovery
if (reqSpellInfo.Mechanic != Mechanics.Discovery &&
// explicit discovery ability
!reqSpellInfo.IsExplicitDiscovery())
{
if (!reportedReqSpells.Contains(absReqSkillOrSpell))
{
Log.outError(LogFilter.Sql, "Spell (ID: {0}) not have MECHANIC_DISCOVERY (28) value in Mechanic field in spell.dbc" +
" and not 100%% chance random discovery ability but listed for spellId {1} (and maybe more) in `skill_discovery_template` table",
absReqSkillOrSpell, spellId);
reportedReqSpells.Add(absReqSkillOrSpell);
}
continue;
}
SkillDiscoveryStorage.Add(reqSkillOrSpell, new SkillDiscoveryEntry(spellId, reqSkillValue, chance));
}
else if (reqSkillOrSpell == 0) // skill case
{
var bounds = Global.SpellMgr.GetSkillLineAbilityMapBounds(spellId);
if (bounds.Empty())
{
Log.outError(LogFilter.Sql, "Spell (ID: {0}) not listed in `SkillLineAbility.dbc` but listed with `reqSpell`=0 in `skill_discovery_template` table", spellId);
continue;
}
foreach (var _spell_idx in bounds)
SkillDiscoveryStorage.Add(-(int)_spell_idx.SkillLine, new SkillDiscoveryEntry(spellId, reqSkillValue, chance));
}
else
{
Log.outError(LogFilter.Sql, "Spell (ID: {0}) have negative value in `reqSpell` field in `skill_discovery_template` table", spellId);
continue;
}
++count;
}
while (result.NextRow());
if (ssNonDiscoverableEntries.Length != 0)
Log.outError(LogFilter.Sql, "Some items can't be successfully discovered: have in chance field value < 0.000001 in `skill_discovery_template` DB table . List:\n{0}", ssNonDiscoverableEntries.ToString());
// report about empty data for explicit discovery spells
foreach (var spellEntry in Global.SpellMgr.GetSpellInfoStorage().Values)
{
// skip not explicit discovery spells
if (!spellEntry.IsExplicitDiscovery())
continue;
if (!SkillDiscoveryStorage.ContainsKey((int)spellEntry.Id))
Log.outError(LogFilter.Sql, "Spell (ID: {0}) is 100% chance random discovery ability but not have data in `skill_discovery_template` table", spellEntry.Id);
}
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} skill discovery definitions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
}
public static uint GetExplicitDiscoverySpell(uint spellId, Player player)
{
// explicit discovery spell chances (always success if case exist)
// in this case we have both skill and spell
var tab = SkillDiscoveryStorage.LookupByKey((int)spellId);
if (tab.Empty())
return 0;
var bounds = Global.SpellMgr.GetSkillLineAbilityMapBounds(spellId);
uint skillvalue = !bounds.Empty() ? (uint)player.GetSkillValue((SkillType)bounds.FirstOrDefault().SkillLine) : 0;
float full_chance = 0;
foreach (var item_iter in tab)
if (item_iter.reqSkillValue <= skillvalue)
if (!player.HasSpell(item_iter.spellId))
full_chance += item_iter.chance;
float rate = full_chance / 100.0f;
float roll = (float)RandomHelper.randChance() * rate; // roll now in range 0..full_chance
foreach (var item_iter in tab)
{
if (item_iter.reqSkillValue > skillvalue)
continue;
if (player.HasSpell(item_iter.spellId))
continue;
if (item_iter.chance > roll)
return item_iter.spellId;
roll -= item_iter.chance;
}
return 0;
}
public static bool HasDiscoveredAllSpells(uint spellId, Player player)
{
var tab = SkillDiscoveryStorage.LookupByKey((int)spellId);
if (tab.Empty())
return true;
foreach (var item_iter in tab)
if (!player.HasSpell(item_iter.spellId))
return false;
return true;
}
public static uint GetSkillDiscoverySpell(uint skillId, uint spellId, Player player)
{
uint skillvalue = skillId != 0 ? (uint)player.GetSkillValue((SkillType)skillId) : 0;
// check spell case
var tab = SkillDiscoveryStorage.LookupByKey((int)spellId);
if (!tab.Empty())
{
foreach (var item_iter in tab)
{
if (RandomHelper.randChance(item_iter.chance * WorldConfig.GetFloatValue(WorldCfg.RateSkillDiscovery)) &&
item_iter.reqSkillValue <= skillvalue &&
!player.HasSpell(item_iter.spellId))
return item_iter.spellId;
}
return 0;
}
if (skillId == 0)
return 0;
// check skill line case
tab = SkillDiscoveryStorage.LookupByKey(-(int)skillId);
if (!tab.Empty())
{
foreach (var item_iter in tab)
{
if (RandomHelper.randChance(item_iter.chance * WorldConfig.GetFloatValue(WorldCfg.RateSkillDiscovery)) &&
item_iter.reqSkillValue <= skillvalue &&
!player.HasSpell(item_iter.spellId))
return item_iter.spellId;
}
return 0;
}
return 0;
}
static MultiMap<int, SkillDiscoveryEntry> SkillDiscoveryStorage = new MultiMap<int, SkillDiscoveryEntry>();
}
public class SkillDiscoveryEntry
{
public SkillDiscoveryEntry(uint _spellId = 0, uint req_skill_val = 0, float _chance = 0)
{
spellId = _spellId;
reqSkillValue = req_skill_val;
chance = _chance;
}
public uint spellId; // discavered spell
public uint reqSkillValue; // skill level limitation
public float chance; // chance
}
}
@@ -0,0 +1,227 @@
/*
* Copyright (C) 2012-2017 CypherCore <http://github.com/CypherCore>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Framework.Database;
using Game.Entities;
using System.Collections.Generic;
namespace Game.Spells
{
public class SkillExtraItems
{
// loads the extra item creation info from DB
public static void LoadSkillExtraItemTable()
{
uint oldMSTime = Time.GetMSTime();
SkillExtraItemStorage.Clear(); // need for reload
// 0 1 2 3
SQLResult result = DB.World.Query("SELECT spellId, requiredSpecialization, additionalCreateChance, additionalMaxNum FROM skill_extra_item_template");
if (result.IsEmpty())
{
Log.outError(LogFilter.ServerLoading, "Loaded 0 spell specialization definitions. DB table `skill_extra_item_template` is empty.");
return;
}
uint count = 0;
do
{
uint spellId = result.Read<uint>(0);
if (!Global.SpellMgr.HasSpellInfo(spellId))
{
Log.outError(LogFilter.Sql, "Skill specialization {0} has non-existent spell id in `skill_extra_item_template`!", spellId);
continue;
}
uint requiredSpecialization = result.Read<uint>(1);
if (!Global.SpellMgr.HasSpellInfo(requiredSpecialization))
{
Log.outError(LogFilter.Sql, "Skill specialization {0} have not existed required specialization spell id {1} in `skill_extra_item_template`!", spellId, requiredSpecialization);
continue;
}
float additionalCreateChance = result.Read<float>(2);
if (additionalCreateChance <= 0.0f)
{
Log.outError(LogFilter.Sql, "Skill specialization {0} has too low additional create chance in `skill_extra_item_template`!", spellId);
continue;
}
byte additionalMaxNum = result.Read<byte>(3);
if (additionalMaxNum == 0)
{
Log.outError(LogFilter.Sql, "Skill specialization {0} has 0 max number of extra items in `skill_extra_item_template`!", spellId);
continue;
}
SkillExtraItemEntry skillExtraItemEntry = new SkillExtraItemEntry();
skillExtraItemEntry.requiredSpecialization = requiredSpecialization;
skillExtraItemEntry.additionalCreateChance = additionalCreateChance;
skillExtraItemEntry.additionalMaxNum = additionalMaxNum;
SkillExtraItemStorage[spellId] = skillExtraItemEntry;
++count;
}
while (result.NextRow());
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} spell specialization definitions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
}
public static bool CanCreateExtraItems(Player player, uint spellId, ref float additionalChance, ref byte additionalMax)
{
// get the info for the specified spell
var specEntry = SkillExtraItemStorage.LookupByKey(spellId);
if (specEntry == null)
return false;
// the player doesn't have the required specialization, return false
if (!player.HasSpell(specEntry.requiredSpecialization))
return false;
// set the arguments to the appropriate values
additionalChance = specEntry.additionalCreateChance;
additionalMax = specEntry.additionalMaxNum;
// enable extra item creation
return true;
}
static Dictionary<uint, SkillExtraItemEntry> SkillExtraItemStorage = new Dictionary<uint,SkillExtraItemEntry>();
}
class SkillExtraItemEntry
{
public SkillExtraItemEntry(uint rS = 0, float aCC = 0f, byte aMN = 0)
{
requiredSpecialization = rS;
additionalCreateChance = aCC;
additionalMaxNum = aMN;
}
// the spell id of the specialization required to create extra items
public uint requiredSpecialization;
// the chance to create one additional item
public float additionalCreateChance;
// maximum number of extra items created per crafting
public byte additionalMaxNum;
}
public class SkillPerfectItems
{
// loads the perfection proc info from DB
public static void LoadSkillPerfectItemTable()
{
uint oldMSTime = Time.GetMSTime();
SkillPerfectItemStorage.Clear(); // reload capability
// 0 1 2 3
SQLResult result = DB.World.Query("SELECT spellId, requiredSpecialization, perfectCreateChance, perfectItemType FROM skill_perfect_item_template");
if (result.IsEmpty())
{
Log.outError(LogFilter.ServerLoading, "Loaded 0 spell perfection definitions. DB table `skill_perfect_item_template` is empty.");
return;
}
uint count = 0;
do
{
uint spellId = result.Read<uint>(0);
if (!Global.SpellMgr.HasSpellInfo(spellId))
{
Log.outError(LogFilter.Sql, "Skill perfection data for spell {0} has non-existent spell id in `skill_perfect_item_template`!", spellId);
continue;
}
uint requiredSpecialization = result.Read<uint>(1);
if (!Global.SpellMgr.HasSpellInfo(requiredSpecialization))
{
Log.outError(LogFilter.Sql, "Skill perfection data for spell {0} has non-existent required specialization spell id {1} in `skill_perfect_item_template`!", spellId, requiredSpecialization);
continue;
}
float perfectCreateChance = result.Read<float>(2);
if (perfectCreateChance <= 0.0f)
{
Log.outError(LogFilter.Sql, "Skill perfection data for spell {0} has impossibly low proc chance in `skill_perfect_item_template`!", spellId);
continue;
}
uint perfectItemType = result.Read<uint>(3);
if (Global.ObjectMgr.GetItemTemplate(perfectItemType) == null)
{
Log.outError(LogFilter.Sql, "Skill perfection data for spell {0} references non-existent perfect item id {1} in `skill_perfect_item_template`!", spellId, perfectItemType);
continue;
}
SkillPerfectItemStorage[spellId] = new SkillPerfectItemEntry(requiredSpecialization, perfectCreateChance, perfectItemType);
++count;
}
while (result.NextRow());
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} spell perfection definitions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
}
public static bool CanCreatePerfectItem(Player player, uint spellId, ref float perfectCreateChance, ref uint perfectItemType)
{
var entry = SkillPerfectItemStorage.LookupByKey(spellId);
// no entry in DB means no perfection proc possible
if (entry == null)
return false;
// if you don't have the spell needed, then no procs for you
if (!player.HasSpell(entry.requiredSpecialization))
return false;
// set values as appropriate
perfectCreateChance = entry.perfectCreateChance;
perfectItemType = entry.perfectItemType;
// and tell the caller to start rolling the dice
return true;
}
static Dictionary<uint, SkillPerfectItemEntry> SkillPerfectItemStorage = new Dictionary<uint, SkillPerfectItemEntry>();
}
// struct to store information about perfection procs
// one entry per spell
class SkillPerfectItemEntry
{
public SkillPerfectItemEntry(uint rS = 0, float pCC = 0f, uint pIT = 0)
{
requiredSpecialization = rS;
perfectCreateChance = pCC;
perfectItemType = pIT;
}
// the spell id of the spell required - it's named "specialization" to conform with SkillExtraItemEntry
public uint requiredSpecialization;
// perfection proc chance
public float perfectCreateChance;
// itemid of the resulting perfect item
public uint perfectItemType;
}
}