C#:
/*
This plugin add unique skills tree for users.
User on Botov-NET rust servers.
-----------
MIT License
Copyright (c) 2015 by AlexALX
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND...
*/
// Reference: Newtonsoft.Json
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Core.Configuration;
using Oxide.Plugins;
using UnityEngine;
using System;
using Newtonsoft.Json;
using Rust;
using StudyCore;
public static class StudyGlobals {
public const string Version = "0.0.6";
public const string DataFileName = "StudyData";
}
namespace Oxide.Plugins
{
[Info("Self Study", "AlexALX", StudyGlobals.Version)]
public class SelfStudy : RustPlugin
{
private readonly Study StudyInstance;
private DynamicConfigFile StudyDataFile;
private Oxide.Plugins.Timer SaveTimer;
[PluginReference] Plugin RustVip;
[PluginReference] Plugin ClansStudy;
[PluginReference] Plugin ZoneManager;
public bool IsVIP(BasePlayer player) {
return (bool)(RustVip?.Call("IsVIP",player) ?? false);
}
public float GetClanBonus(string player, string bonus) {
return (float)(ClansStudy?.Call("GetClanBonus", player, bonus) ?? 0f);
}
public string GetClanBonuses(BasePlayer player) {
return (string)(ClansStudy?.Call("GetClanBonuses", player.userID.ToString()) ?? "");
}
public float GetWeaponBonus(string sid, string weapon) {
return (float)(ClansStudy?.Call("GetWeaponBonus", sid, weapon) ?? 0f);
}
public bool IsInArena(BasePlayer player) {
return (bool)(ZoneManager?.Call("isPlayerInZone", "Deathmatch", player) ?? false);
}
public SelfStudy()
{
//HasConfig = true;
StudyInstance = new Study(this);
/*if (StudyInstance == null) {
return;
}*/
}
public void Print(string msg)
{
Puts("{0}", msg);
}
[HookMethod("Init")]
void Init()
{
Puts(StudyInstance == null ? "Problem initializating Self-Study Instance!" : "Self-Study initialized!");
LoadStudy();
SaveTimer = timer.Repeat(900f, 0, () => StudyInstance.Save());
}
[HookMethod("OnServerInitialized")]
void OnServerInitialized()
{
//Init();
StudyInstance.GenerateItemTable();
StudyInstance.FurnacesCheck((Dictionary<string, string>)StudyDataFile["Furnace"]);
}
[HookMethod("OnServerSave")]
void OnServerSave()
{
StudyInstance.Save();
}
[HookMethod("Unload")]
void Unload()
{
SaveTimer.Destroy();
StudyInstance.Save(true);
StudyInstance.FixItemTable();
}
protected override void LoadDefaultConfig()
{
DefaultConfig();
}
private void DefaultConfig() {
StudyDataFile = Interface.GetMod().DataFileSystem.GetDatafile(StudyGlobals.DataFileName);
StudyDataFile["Profile"] = new Dictionary<string, PlayerInfo>();
StudyDataFile["Furnace"] = new Dictionary<string, string>();
Interface.GetMod().DataFileSystem.SaveDatafile(StudyGlobals.DataFileName);
//var ret = StudyInstance.DefaultConfig();
//Config["settings"] = ret["settings"];
//Config["skills"] = ret["skills"];
Config["settings"] = new Dictionary<string,object>();
Config["skills"] = new Dictionary<string,StudySkill>();
Config["profs"] = new Dictionary<string,StudyProf>();
SaveConfig();
}
public void SaveStudy(Dictionary<string, PlayerInfo> playerConfig, Dictionary<string, string> furnaceConfig) {
if (playerConfig==null||furnaceConfig==null) return;
StudyDataFile["Profile"] = playerConfig;
StudyDataFile["Furnace"] = furnaceConfig;
Interface.GetMod().DataFileSystem.SaveDatafile(StudyGlobals.DataFileName);
}
public void SaveStudyConfig(Dictionary<string, object> settings, Dictionary<string, StudySkill> skills, Dictionary<string, StudyProf> profs) {
Config["settings"] = settings;
Config["skills"] = skills;
Config["profs"] = profs;
SaveConfig();
}
private void LoadStudy() {
LoadConfig();
StudyInstance.LoadConfig(ReadFromConfig<Dictionary<string,object>>("settings"),ReadFromConfig<Dictionary<string,StudySkill>>("skills"),ReadFromConfig<Dictionary<string,StudyProf>>("profs"));
StudyDataFile = Interface.GetMod().DataFileSystem.GetDatafile(StudyGlobals.DataFileName);
StudyDataFile["Profile"] = ReadFromData<Dictionary<string, PlayerInfo>>("Profile");
StudyDataFile["Furnace"] = ReadFromData<Dictionary<string, string>>("Furnace");
StudyInstance.Load((Dictionary<string, PlayerInfo>)StudyDataFile["Profile"],(Dictionary<string, string>)StudyDataFile["Furnace"]);
}
public T ReadFromConfig<T>(string configKey)
{
string serializeObject = JsonConvert.SerializeObject(Config[configKey]);
return JsonConvert.DeserializeObject<T>(serializeObject);
}
public T ReadFromData<T>(string dataKey)
{
string serializeObject = JsonConvert.SerializeObject(StudyDataFile[dataKey]);
return JsonConvert.DeserializeObject<T>(serializeObject);
}
[ChatCommand("fc")]
void cmdChatFix(BasePlayer player, string command, string[] args)
{
var i = 20;
timer.Repeat(0.1f,i,() => SendReply(player, "FIX CHAT #"+(i--)));
}
[ConsoleCommand("study.recalc_manual")]
void cmdReCalc(ConsoleSystem.Arg arg)
{
if (!arg.CheckPermissions()) return;
Print(StudyInstance.ReCalcSkills(false,true));
}
[ConsoleCommand("study.recalc_auto")]
void cmdReCalcAuto(ConsoleSystem.Arg arg)
{
if (!arg.CheckPermissions()) return;
Print(StudyInstance.ReCalcSkills(true,true));
}
[ChatCommand("hunt")]
void cmdChatHunt(BasePlayer player, string command, string[] args)
{
SendReply(player, "Данная команда не используется, напишите <color='#00DD00'>/skill</color>.");
}
[ChatCommand("skill")]
void cmdChatSkill(BasePlayer player, string command, string[] args)
{
SendReply(player, StudyInstance.ChatSkill(player, command, args));
}
[ChatCommand("me")]
void cmdChatMe(BasePlayer player, string command, string[] args)
{
SendReply(player, StudyInstance.ChatMe(player, command, args));
}
[ChatCommand("up")]
void cmdChatUp(BasePlayer player, string command, string[] args)
{
SendReply(player, StudyInstance.ChatUp(player, command, args));
}
[HookMethod("OnPlayerInit")]
void OnPlayerInit(BasePlayer player)
{
StudyInstance.PlayerInit(player);
}
[HookMethod("OnPlayerRespawned")]
void OnPlayerRespawned(BasePlayer player)
{
StudyInstance.PlayerRespawned(player);
}
[HookMethod("OnPlayerDisconnected")]
void OnPlayerDisconnected(BasePlayer player)
{
StudyInstance.PlayerDisconnected(player);
}
[HookMethod("OnItemCraft")]
void OnItemCraft(ItemCraftTask craft)
{
StudyInstance.OnItemCraft(craft);
}
[HookMethod("OnLoseCondition")]
void OnLoseCondition(Item item, ref float amount)
{
if (item.hasCondition) amount = StudyInstance.LoseCondition(item,amount);
}
[HookMethod("OnGather")]
void OnGather(ResourceDispenser dispenser, BaseEntity entity, Item item)
{
StudyInstance.OnGather(dispenser, entity, item);
}
[HookMethod("OnPlayerAttack")]
void OnPlayerAttack(BasePlayer entity, HitInfo hitInfo)
{
StudyInstance.OnPlayerAttack(entity, hitInfo);
}
[HookMethod("OnEntityTakeDamage")]
void OnEntityAttacked(BaseCombatEntity entity, HitInfo hitInfo)
{
//Print(StringPool.Get(hitInfo.HitBone));
StudyInstance.OnEntityAttacked(entity, hitInfo);
}
[HookMethod("OnEntityDeath")]
void OnEntityDeath(BaseCombatEntity entity, HitInfo hitInfo)
{
StudyInstance.OnEntityDeath(entity, hitInfo);
}
[HookMethod("OnEntityBuilt")]
void OnEntityBuilt(Planner planner, UnityEngine.GameObject gameObject)
{
StudyInstance.OnEntityBuilt(planner, gameObject);
}
[HookMethod("OnBuildingBlockUpgrade")]
void OnBuildingBlockUpgrade(BuildingBlock block, BasePlayer player, BuildingGrade.Enum grade)
{
StudyInstance.OnBuildingBlockUpgrade(block, player, grade);
}
[HookMethod("OnItemDeployed")]
void OnItemDeployed(Deployer deployer, BaseEntity baseEntity)
{
StudyInstance.DeployItem(deployer, baseEntity);
}
[HookMethod("OnConsumeFuel")]
void OnConsumeFuel(BaseOven oven, Item fuel, ItemModBurnable burnable)
{
StudyInstance.ConsumeFuel(oven, fuel, burnable);
}
int GetPlayerLvl(string sid) {
return StudyInstance.GetPlayerLvl(sid);
}
}
}
namespace StudyCore
{
class Study
{
private Dictionary<string, PlayerInfo> PlayerConfig;
private Dictionary<string, string> FurnaceConfig;
private Dictionary<int, int> SkillLvlTable;
private Dictionary<int, int> RockLvlTable;
private Dictionary<int, int> WeaponLvlTable;
private Dictionary<int, int> PlayerLvlTable;
private readonly SelfStudy PluginInstance;
private Dictionary<string, List<string>> CorrectResources;
private Dictionary<string, PlayerTmp> PlayerTmpInfo;
private Dictionary<string, StudyProf> StudyProfs;
private Dictionary<string, StudySkill> StudySkills;
private Dictionary<string, Dictionary<string,StudySkill>> StudySTypes;
//private float TotalGatherX;
private float TotalGatherC;
private float StartGatherX;
private float WeaponCondX;
private float XPMul;
private Dictionary<string, ItemInfo> ItemTable;
private Dictionary<string, Dictionary<int,string>> StudyEvents;
public static DateTime epoch = new System.DateTime(1970, 1, 1);
public Study(SelfStudy pluginInstance)
{
PluginInstance = pluginInstance;
PlayerConfig = new Dictionary<string, PlayerInfo>();
FurnaceConfig = new Dictionary<string, string>();
SkillLvlTable = GenerateLvlTable(50000,50,0.0784f);
RockLvlTable = GenerateLvlTable(1000,10,2,1);
WeaponLvlTable = GenerateLvlTable(8000,30,0.2146f);
PlayerLvlTable = GenerateLvlTable(2225,99,0.01608f,0.2f);
CorrectResources = new Dictionary<string, List<string>>(){
{ "Tree", new List<string>(new string[] {"rock","stonehatchet","hatchet","axe_salvaged"} ) },
{ "Ore", new List<string>(new string[] {"rock","stone_pickaxe","pickaxe","icepick_salvaged","hammer_salvaged"} ) }
};
PlayerTmpInfo = new Dictionary<string, PlayerTmp>();
ItemTable = new Dictionary<string, ItemInfo>();
//ItemTable = GenerateItemTable();
StartGatherX = 1f;
//TotalGatherX = 2f;
//TotalGatherC = 0.5f;
WeaponCondX = 0.5f;
XPMul = 1f;
StudyProfs = new Dictionary<string, StudyProf>();
StudyProfs["Tree"] = new StudyProf(new string[] {"лесоруба","Лесоруб"},"Tree",12f,new Dictionary<string, StudySkillOpts>{
{"Tree",new StudySkillOpts("добыча дерева",5f,"x")}
//{"прочность",new object[]{1.25f,"+"}}
});
StudyProfs["Ore"] = new StudyProf(new string[] {"каменоломщика","Каменоломщик"},"Ore",22f,new Dictionary<string, StudySkillOpts>{
{"Ore",new StudySkillOpts("добыча камня",5f,"x")}
//{"прочность",new object[]{0.7f,"+"}}
});
StudyProfs["Flesh"] = new StudyProf(new string[] {"охотника","Охотник"},"Flesh",3f,new Dictionary<string, StudySkillOpts>{
{"Flesh",new StudySkillOpts("добыча животных",5f,"x")}
//{"прочность",new object[]{0.7f,"+"}}
});
StudyProfs["Kill"] = new StudyProf(new string[] {"убийцы","Убийца"},"Kill",3f,new Dictionary<string, StudySkillOpts>{
{"Kill",new StudySkillOpts("урон игрокам",1.25f,"+")}
});
StudyProfs["Build"] = new StudyProf(new string[] {"строителя","Строитель"},"Build",3f,new Dictionary<string, StudySkillOpts>{
{"Build",new StudySkillOpts("стоимость постройки",0.75f,"-")}
});
StudySkills = new Dictionary<string, StudySkill>();
StudySkills["power"] = new StudySkill("Сила",90,new Dictionary<string, StudySkillOpts>(){
{"damage",new StudySkillOpts("урон",1.25f,"+")}
},6);
StudySkills["defence"] = new StudySkill("Защита",90,new Dictionary<string, StudySkillOpts>(){
{"defence",new StudySkillOpts("оборона",1.25f,"+")}
},5);
StudySkills["lovk"] = new StudySkill("Ловкость",80,new Dictionary<string, StudySkillOpts>(){
{"lovk",new StudySkillOpts("шанс уклонения",1.1f,"")}
},4);
StudySkills["int"] = new StudySkill("Интелект",80,new Dictionary<string, StudySkillOpts>(){
{"craft",new StudySkillOpts("крафт",0.85f,"-")},
{"kuznec",new StudySkillOpts("кузнец",1.5f,"+")}
},4);
StudySkills["master"] = new StudySkill("Мастер",80,new Dictionary<string, StudySkillOpts>(){
{"total",new StudySkillOpts("бонус ко всему",1.05f,"+")}
},5);
StudySkills["craft"] = new StudySkill("Инженер",80,new Dictionary<string, StudySkillOpts>(){
{"craft",new StudySkillOpts("крафт",0.65f,"-")}
},6,15);
StudySkills["vinos"] = new StudySkill("Выносливость",60,new Dictionary<string, StudySkillOpts>(){
{"vinos",new StudySkillOpts("",1.5f,"+")}
},1);
StudySkills["stalker"] = new StudySkill("Сталкер",50,new Dictionary<string, StudySkillOpts>(){
{"rad",new StudySkillOpts("устойчивость к радиации",1.5f,"+")}
},4,30);/*
StudySkills["speed"] = new StudySkill("Атлет",20,new Dictionary<string, object[]>(){
{"speed",new object[]{"скорость бега",1.05f,"+"}}
},6,60);*/
StudyEvents = new Dictionary<string, Dictionary<int,string>>();
StudyEvents["Build"] = new Dictionary<int,string>(){
{20,"Вы получили доступ к команде <color='#00DD00'>/up</color>! Теперь вы можете автоматически обновлять постройки до дерева."},
{35,"Вы получили доступ к команде <color='#00DD00'>/up stone</color>! Теперь вы можете автоматически обновлять постройки до камня."}
};
StudyEvents["playerlvl"] = new Dictionary<int,string>(){
{50,"Вы получили доступ к команде <color='#00DD00'>/me reset</color>! Теперь вы можете сбрасывать ваши навыки <color='#DD0000'>раз в неделю</color>."}
};
}
private void PostInit() {
StudySTypes = new Dictionary<string, Dictionary<string,StudySkill>>();
foreach(KeyValuePair<string,StudySkill> kvp in StudySkills) {
foreach(KeyValuePair<string,StudySkillOpts> kvs in kvp.Value.Skills) {
if (!StudySTypes.ContainsKey(kvs.Key)) StudySTypes[kvs.Key] = new Dictionary<string,StudySkill>();
StudySTypes[kvs.Key][kvp.Key] = kvp.Value;
}
}
/*foreach( KeyValuePair<string, Dictionary<string,StudySkill>> kvp in StudySTypes )
{
Print("Key = " + kvp.Key.ToString() + ", Values = " + string.Join(", ", kvp.Value.Select(f => f.ToString()).ToArray()).ToString());
}*/
}
/*
public Dictionary<string,object> DefaultConfig() {
var config = new Dictionary<string,object>();
config["settings"] = new Dictionary<string,object>();
((Dictionary<string,object>)config["settings"]).Add("StartGatherX",StartGatherX);
((Dictionary<string,object>)config["settings"]).Add("WeaponCondX",WeaponCondX);
config["skills"] = new Dictionary<string,StudySkill>();
foreach(KeyValuePair<string,StudySkill> kvp in StudySkills) {
((Dictionary<string,StudySkill>)config["skills"]).Add(kvp.Key,kvp.Value);
}
return config;
}*/
public void LoadConfig(Dictionary<string,object> settings, Dictionary<string,StudySkill> skills, Dictionary<string,StudyProf> profs) {
var save = false;
var nsettings = new Dictionary<string,object>();
var nskills = new Dictionary<string,StudySkill>();
var nprofs = new Dictionary<string,StudyProf>();
if (settings==null||settings.Count==0||skills==null||skills.Count==0||profs==null||profs.Count==0) save = true;
StartGatherX = (float)(settings!=null&&settings.ContainsKey("StartGatherX")?Convert.ToSingle(settings["StartGatherX"]):StartGatherX);
nsettings.Add("StartGatherX",StartGatherX);
WeaponCondX = (float)(settings!=null&&settings.ContainsKey("WeaponCondX")?Convert.ToSingle(settings["WeaponCondX"]):WeaponCondX);
nsettings.Add("WeaponCondX",WeaponCondX);
XPMul = (float)(settings!=null&&settings.ContainsKey("XPMul")?Convert.ToSingle(settings["XPMul"]):XPMul);
nsettings.Add("XPMul",XPMul);
StudySkills = (skills!=null&&skills.Count>0?skills:StudySkills);
/*foreach(KeyValuePair<string,StudySkill> kvp in StudySkills) {
foreach(KeyValuePair<string,object[]> kvs in kvp.Value.Skills) {
kvs.Value[1] = (float)Convert.ToSingle(kvs.Value[1]);
}
}*/
nskills = StudySkills;
StudyProfs = (profs!=null&&profs.Count>0?profs:StudyProfs);
/*foreach(KeyValuePair<string,StudyProf> kvp in StudyProfs) {
foreach(KeyValuePair<string,object[]> kvs in kvp.Value.Skills) {
kvs.Value[1] = (float)Convert.ToSingle(kvs.Value[1]);
}
}*/
nprofs = StudyProfs;
//Print(StudySkills["power"].Skills["damage"].Mul.GetType().ToString());
if (save) PluginInstance.SaveStudyConfig(nsettings,nskills,nprofs);
PostInit();
}
public Dictionary<string, ItemInfo> GenerateItemTable()
{
var itemDict = new Dictionary<string, ItemInfo>();
var itemsDefinition = ItemManager.GetItemDefinitions();
foreach (var itemDefinition in itemsDefinition)
{
var newInfo = new ItemInfo {Shortname = itemDefinition.shortname, ItemId = itemDefinition.itemid, ItemCategory = itemDefinition.category.ToString()};
var blueprint = ItemManager.FindBlueprint(itemDefinition);
if (blueprint != null) newInfo.BlueprintTime = blueprint.time;
if (!itemDict.ContainsKey(itemDefinition.displayName.translated.ToLower())) itemDict.Add(itemDefinition.displayName.translated.ToLower(), newInfo);
}
ItemTable = itemDict;
//var blueprintDefinitions = Resources.LoadAll<ItemBlueprint>("items/").ToList();
/*var itemDefinitions = Resources.LoadAll<ItemDefinition>("items/").ToList();
foreach (ItemDefinition itemDefinition in itemDefinitions) {
var newInfo = new ItemInfo {Shortname = itemDefinition.shortname, ItemId = itemDefinition.itemid, ItemCategory = itemDefinition.category.ToString()};
var blueprint = ItemManager.FindBlueprint(itemDefinition);
if (blueprint != null) newInfo.BlueprintTime = blueprint.time;
itemDict.Add(itemDefinition.displayName.english, newInfo);
Print(itemDefinition.displayName.english);
}*/
/*Print(blueprintDefinitions.Count.ToString());
foreach (ItemBlueprint bp in blueprintDefinitions) {
//var newInfo = new ItemInfo {Shortname = itemDefinition.shortname, ItemId = itemDefinition.itemid, ItemCategory = itemDefinition.category.ToString()};
//itemDict.Add(bp.targetItem.displayName.translated.ToLower(), newInfo);
Print(bp.time.ToString());
}*//*
foreach(KeyValuePair<string,ItemInfo> kvp in itemDict) {
Print(kvp.Value.BlueprintTime.ToString());
}*/
return itemDict;
}
public void FixItemTable()
{
var itemsDefinition = ItemManager.GetItemDefinitions();
foreach (var itemDefinition in itemsDefinition)
{
var blueprint = ItemManager.FindBlueprint(itemDefinition);
if (blueprint != null && ItemTable.ContainsKey(itemDefinition.displayName.translated.ToLower()))
blueprint.time = ItemTable[itemDefinition.displayName.translated.ToLower()].BlueprintTime;
}
}
public int GetPlayerLvl(string sid) {
var info = PlayerInfo(null,sid);
if (info==null) return 0;
return info.Info.Level;
}
private PlayerInfo PlayerInfo(BasePlayer player, string sid = "")
{
string steamId = "";
if (sid!="") steamId = sid;
else steamId = SteamId(player);
if (PlayerConfig.ContainsKey(steamId)) return PlayerConfig[steamId];
if (sid!="") return null;
PlayerConfig[steamId] = new PlayerInfo(player.displayName);
//PluginInstance.SaveRPG(PlayerConfig, PlayersFurnaces);
return PlayerConfig[steamId];
}
private PlayerTmp PlayerTmp(BasePlayer player)
{
string steamId = SteamId(player);
if (PlayerTmpInfo.ContainsKey(steamId)) return PlayerTmpInfo[steamId];
PlayerTmpInfo[steamId] = new PlayerTmp();
//PluginInstance.SaveRPG(PlayerConfig, PlayersFurnaces);
return PlayerTmpInfo[steamId];
}
private string SteamId(BasePlayer player)
{
return player.userID.ToString();
}
private void ChatMessage(BasePlayer player, string message)
{
player.ChatMessage(string.Format("{0}", message));
}
private void Print(string msg)
{
PluginInstance.Print(msg);
}
private float StudyGetType(PlayerInfo playerInfo,string type, float def = 0f, BasePlayer player = null) {
float ret = 0f;
foreach(KeyValuePair<string,StudySkill> kvp in StudySTypes[type]) {
var mul = (float)kvp.Value.Skills[type].Mul;
if (mul>1) mul -= 1;
else mul = 1-mul;
if (playerInfo.PlayerOptions.ContainsKey(kvp.Key)) {
mul = playerInfo.PlayerOptions[kvp.Key].Points*(mul/kvp.Value.Points);
ret += mul;
}
}
if (ret==0f) ret = def;
if (type=="total") {
var clanbonus = PluginInstance.GetClanBonus(SteamId(player),"master");
if (clanbonus>0f) ret += clanbonus;
}
return ret;
}
private float StudyProfType(PlayerInfo playerInfo,string type) {
if (!playerInfo.PlayerSkills.ContainsKey(type)) return 0f;
var mul = (float)StudyProfs[type].Skills[type].Mul;
if (mul>1) mul -= 1;
else mul = 1-mul;
mul = playerInfo.PlayerSkills[type].Info.Level*(mul/SkillLvlTable.Count);
return mul;
}
private Dictionary<int, int> GenerateLvlTable(int total, int lvl, float mul, float min = 0, bool print = false)
{
Dictionary<int, int> GeneratedTbl = new Dictionary<int, int>();
for (int i = 1; i <= lvl; i++)
{
if (min==0) {
GeneratedTbl[i] = (int)Math.Ceiling((decimal)(total/100*(mul*i)));
} else {
if (i==1) {
GeneratedTbl[i] = (int)Math.Ceiling((decimal)(total/100*min));
} else {
GeneratedTbl[i] = (int)Math.Ceiling((decimal)(total/100*(min+mul*(i-1))));
}
}
}
if (print) {
var count = 0;
foreach( KeyValuePair<int, int> kvp in GeneratedTbl )
{
Print("Level = " + kvp.Key.ToString() + ", Value = " + kvp.Value.ToString());
count += kvp.Value;
}
Print("Total value: " + count.ToString());
}
return GeneratedTbl;
}
public void Save(bool unload = false) {
if (unload) {
FurnacesCheck(FurnaceConfig);
PlayersCheck(PlayerConfig);
}
PluginInstance.SaveStudy(PlayerConfig,FurnaceConfig);
}
public void Load(Dictionary<string, PlayerInfo> playerConfig, Dictionary<string, string> furnaceConfig) {
if (playerConfig!=null) PlayerConfig = playerConfig;
if (furnaceConfig!=null) FurnaceConfig = furnaceConfig;
}
public void FurnacesCheck(Dictionary<string, string> furnaceConfig) {
var furnaces = new Dictionary<string, string>();
if (furnaceConfig!=null&&furnaceConfig.Count>0) {
BaseOven[] finds = UnityEngine.Object.FindObjectsOfType(typeof(BaseOven)) as BaseOven[];
foreach (BaseOven find in finds) {
if (find.ToString().Contains("furnace_deployed")) {
var instanceId = OvenId(find);
if (furnaceConfig.ContainsKey(instanceId)) furnaces[instanceId] = furnaceConfig[instanceId];
}
}
}
FurnaceConfig = furnaces;
}
private bool CheckTime(double last, int level) {
var time = CurrentTime();
if (level<=3) { if (last+60*60*24*3<time) return false; }
else if (level<=10) { if (last+60*60*24*14<time) return false; }
else if (level<=30) { if (last+60*60*24*30<time) return false; }
else if (level<=60) { if (last+60*60*24*90<time) return false; }
else if (last+60*60*24*180<time) return false;
return true;
}
public void PlayersCheck(Dictionary<string, PlayerInfo> playerConfig) {
var players = new Dictionary<string, PlayerInfo>();
if (playerConfig!=null&&playerConfig.Count>0) {
foreach (KeyValuePair<string, PlayerInfo> kvp in playerConfig) {
if ((kvp.Value.Info.Level>1 || kvp.Value.Info.XP>0 || kvp.Value.PlayerSkills.Count>0 || kvp.Value.WeaponSkills.Count>0) && CheckTime(kvp.Value.LastVisit, kvp.Value.Info.Level))
players[kvp.Key] = kvp.Value;
}
}
PlayerConfig = players;
}
public void PlayerInit(BasePlayer player)
{
var steamId = SteamId(player);
if (PlayerConfig.ContainsKey(steamId)) {
var playerInfo = PlayerInfo(player);
playerInfo.SteamName = player.displayName;
playerInfo.LastVisit = CurrentTime();
}
}
public void PlayerRespawned(BasePlayer player) {
if (PluginInstance.IsInArena(player)) return;
var playerInfo = PlayerInfo(player);
if (playerInfo.Info.Level>0) {
var add = 0.5f/PlayerLvlTable.Count*playerInfo.Info.Level;
player.health = player.health+(player.health*add);
player.metabolism.calories.Add(player.metabolism.calories.@value*add);
player.metabolism.hydration.Add(player.metabolism.hydration.@value*add);
}
}
public void PlayerDisconnected(BasePlayer player)
{
string steamId = SteamId(player);
if (PlayerTmpInfo.ContainsKey(steamId)) {
PlayerTmpInfo.Remove(steamId);
}
}
public void OnItemCraft(ItemCraftTask craft) {
var itemName = craft.blueprint.targetItem.displayName.translated.ToLower();
if (!ItemTable.ContainsKey(itemName)||!StudySTypes.ContainsKey("craft")) return;
var blueprintTime = ItemTable[itemName].BlueprintTime;
craft.blueprint.time = blueprintTime-blueprintTime*StudyGetType(PlayerInfo(craft.owner),"craft")*(1-StudyGetType(PlayerInfo(craft.owner),"total",0f,craft.owner));
//Print(craft.blueprint.time.ToString());
}
public float LoseCondition(Item item, float amount)
{
var player = item.GetOwnerPlayer();
if (player==null) return amount;
if (PluginInstance.IsInArena(player)) return amount;
/*var playerTmp = PlayerTmp(player);
if (playerTmp.Cache.ContainsKey("condition") && ((Dictionary<string,float>)playerTmp.Cache["condition"]).ContainsKey(item.info.shortname)) {
var mul = ((Dictionary<string,float>)playerTmp.Cache["condition"])[item.info.shortname];
if (mul<1) amount *= mul;
return amount;
}*/
var playerInfo = PlayerInfo(player);
var mul = 1f;
if (playerInfo.WeaponSkills.ContainsKey(item.info.shortname)) {
var total = WeaponLvlTable.Count;
if (item.info.shortname=="rock") total = RockLvlTable.Count;
mul = 1-(WeaponCondX/total*playerInfo.WeaponSkills[item.info.shortname].Info.Level);
}
var clancond = PluginInstance.GetClanBonus(SteamId(player),"cond");
if (clancond>0f) mul -= clancond;
if (mul<1f) amount *= mul;
return amount;
}
private bool IsHuman(object ent, bool player = false) {
//Print(ent.ToString());
if (ent!=null && (ent.ToString().Contains("player") || ent.ToString().Contains("animals") && !player) && !ent.ToString().Contains("corpse")) return true;
return false;
}
public void OnPlayerAttack(BasePlayer attacker, HitInfo hitInfo) {
var ent = hitInfo.HitEntity;
if (ent!=null && ent.GetComponent<ResourceDispenser>()!=null||IsNPC(attacker)) return;
var player = attacker; //hitInfo.Initiator as BasePlayer;
if (PluginInstance.IsInArena(player)) return;
var playerInfo = PlayerInfo(player);
Item weaponObj = (hitInfo.Weapon as HeldEntity).GetItem();
if (weaponObj==null) return;
string weapon = weaponObj.info.shortname;
if (weapon=="syringe_medical"||weapon=="torch") return;
//var meleeItem = player.svActiveItem.GetHeldEntity() as BaseMelee;
//var cond = 1f; //meleeItem.GetGatherInfoFromIndex(dispenser.gatherType);
var addxp = 0.25f;
if (IsHuman(ent)) addxp = 1f;
var ret = CalcAction(player,"Attack",new Dictionary<string, object>(){
{"Type","Flesh"},
{"AddXP",addxp},
{"Weapon",weapon},
{"WeaponObj",weaponObj},
//{"ConditionLost",cond}
});
if (ret==null||ent==null||ent.GetComponent<BasePlayer>()==null&&ent.GetComponent<BaseNPC>()==null) return;
float skillmul = StudyGetType(playerInfo,"damage");
float profmul = StudyProfType(playerInfo,"Kill");
float mul = skillmul+profmul+(1-StudyGetType(PlayerInfo(player),"total",1f,player));
var clanbonus = PluginInstance.GetClanBonus(SteamId(player),"damage");
if (clanbonus>0f) mul += clanbonus;
clanbonus = PluginInstance.GetWeaponBonus(SteamId(player),weapon);
if (clanbonus>0f) mul += clanbonus;
if (mul>0f) {
for (int i = 0; i < hitInfo.damageTypes.types.Length; i++) {
if (hitInfo.damageTypes.types[i]>0f) hitInfo.damageTypes.types[i] += hitInfo.damageTypes.types[i]*mul;
}
}
}
private bool IsNPC(BasePlayer player) {
if (player.userID < 76560000000000000L) return true;
return false;
}
public void DeployItem(Deployer deployer, BaseEntity baseEntity)
{
var player = deployer.ownerPlayer;
var item = deployer.GetItem();
var itemDef = item.info;
var type = baseEntity.GetType();
if (type != typeof (BaseOven) || !itemDef.displayName.translated.ToLower().Equals("furnace")) return;
var baseOven = (BaseOven)baseEntity;
var instanceId = OvenId(baseOven);
if (FurnaceConfig.ContainsKey(instanceId))
{
ChatMessage(player, "Ошибка привязки печки к игроку, сообщите владельцу сервера: "+instanceId);
return;
}
FurnaceConfig.Add(instanceId, SteamId(player));
}
private string OvenId(BaseOven oven)
{
var position = oven.transform.position;
return String.Format("X{0} Y{1} Z{2}", position.x, position.y, position.z);
}
public void ConsumeFuel(BaseOven oven, Item fuel, ItemModBurnable burnable)
{
var instanceId = OvenId(oven);
if (!FurnaceConfig.ContainsKey(instanceId))
return;
//var player = BasePlayer.FindByID(Convert.ToUInt64(FurnaceConfig[instanceId]));
var playerInfo = PlayerInfo(null,FurnaceConfig[instanceId]);
var clanbonus = PluginInstance.GetClanBonus(FurnaceConfig[instanceId],"kuznec");
var type = StudySTypes.ContainsKey("int")?"int":"kuznec";
if (clanbonus==0f && (playerInfo==null || !playerInfo.PlayerOptions.ContainsKey(type) || playerInfo.PlayerOptions[type].Points==0)) return;
var mul = (playerInfo!=null?StudyGetType(playerInfo,"kuznec"):0f);
if (clanbonus>0f) mul += clanbonus;
if (mul==0f) return;
var chs = mul*0.5f;
var rand = UnityEngine.Random.Range(0f,1f);
if (rand<=chs) {
var amountToGive = 1;
var itemList = oven.inventory.itemList;
var itensCanMelt = (from item in itemList let itemModCookable = item.info.GetComponent<ItemModCookable>() where itemModCookable != null select item).ToList();
foreach (var item in itensCanMelt)
{
var itemModCookable = item.info.GetComponent<ItemModCookable>();
oven.inventory.Take(null, item.info.itemid, amountToGive);
var itemToGive = ItemManager.Create(itemModCookable.becomeOnCooked, amountToGive, false);
//Print(itemToGive.info.shortname);
if (!itemToGive.MoveToContainer(oven.inventory, -1, true))
itemToGive.Drop(oven.inventory.dropPosition, oven.inventory.dropVelocity);
}
}
}
public void OnEntityAttacked(BaseCombatEntity entity, HitInfo hitInfo) {
if (hitInfo.Initiator!=null && IsHuman(hitInfo.Initiator) && entity.ToPlayer()) {
var player = entity as BasePlayer;
if (!IsNPC(player)) {
if (PluginInstance.IsInArena(player)) return;
BasePlayer attacker = null;
bool selfdmg = false;
if (IsHuman(hitInfo.Initiator,true)) {
attacker = hitInfo.Initiator as BasePlayer;
if (attacker.userID==player.userID) selfdmg = true;
}
var playerInfo = PlayerInfo(player);
if (!selfdmg) {
var chs = StudyGetType(playerInfo,"lovk")*(1+StudyGetType(playerInfo,"total",0f,player))*100;
var rand = UnityEngine.Random.Range(0f,100f);
if (rand<=chs) {
ChatMessage(player,"<color='#00DD00'>Вы уклонились от атаки!</color>");
if (attacker!=null) ChatMessage(attacker,"<color='#DD0000'>Игрок " + player.displayName + " уклонился от атаки!</color>");
while (hitInfo.damageTypes.Total() > 0) {
hitInfo.damageTypes.Set( hitInfo.damageTypes.GetMajorityDamageType(), 0 );
}
hitInfo.HitMaterial = 0;
return;
}
float mul = StudyGetType(playerInfo,"defence")+StudyGetType(playerInfo,"total",0f,player);
var clanbonus = PluginInstance.GetClanBonus(SteamId(player),"defence");
if (clanbonus>0f) mul += clanbonus;
if (mul>0f) {
for (int i = 0; i < hitInfo.damageTypes.types.Length; i++) {
if (hitInfo.damageTypes.types[i]>0f) hitInfo.damageTypes.types[i] -= hitInfo.damageTypes.types[i]*mul;
}
}
} else {
float mul = 0f;
var raddmg = hitInfo.damageTypes.Get(Rust.DamageType.Radiation);
float clanbonus = 0f;
if (raddmg>0f) {
mul = StudyGetType(playerInfo,"rad")+StudyGetType(playerInfo,"total",0f,player);
clanbonus = PluginInstance.GetClanBonus(SteamId(player),"stalker");
if (clanbonus>0f) mul += clanbonus;
hitInfo.damageTypes.Set(Rust.DamageType.Radiation,raddmg-raddmg*mul);
}
mul = StudyGetType(playerInfo,"vinos")+StudyGetType(playerInfo,"total",0f,player);
clanbonus = PluginInstance.GetClanBonus(SteamId(player),"vinos");
if (clanbonus>0f) mul += clanbonus;
if (mul>0f) {
int[] arr = {(int)Rust.DamageType.Cold,(int)Rust.DamageType.Drowned,(int)Rust.DamageType.Heat,(int)Rust.DamageType.Hunger};
for (int i = 0; i < hitInfo.damageTypes.types.Length; i++) {
if (Array.Exists(arr, e => e == i) && hitInfo.damageTypes.types[i]>0f) hitInfo.damageTypes.types[i] -= hitInfo.damageTypes.types[i]*mul;
}
}
}
}
}
}
public void OnEntityDeath(BaseCombatEntity entity, HitInfo hitInfo) {
if (hitInfo.Initiator!=null && IsHuman(entity) && hitInfo.Initiator.ToPlayer() && !IsNPC(hitInfo.Initiator as BasePlayer)) {
var player = hitInfo.Initiator as BasePlayer;
if (PluginInstance.IsInArena(player)) return;
var type = "Flesh";
if (IsHuman(entity,true)) type = "Kill";
//if (player.svActiveItem==null) return;
//var playerInfo = PlayerInfo(player);
if (hitInfo.Weapon==null) return;
Item weaponObj = (hitInfo.Weapon as HeldEntity).GetItem();
string weapon = weaponObj.info.shortname;
//var meleeItem = player.svActiveItem.GetHeldEntity() as BaseMelee;
//var cond = 1f; //meleeItem.GetGatherInfoFromIndex(dispenser.gatherType);
var ret = CalcAction(player,"Kill",new Dictionary<string, object>(){
{"Type",type},
{"ItemAmount",350},
{"Weapon",weapon},
{"WeaponObj",weaponObj},
{"PlayerProf",true},
//{"ConditionLost",cond}
});
if (ret==null) return;
/*
if (player.svActiveItem.condition>0f && (float)ret["totalamount"]>0) {
player.svActiveItem.condition += cond.conditionLost*(float)ret["totalamount"];
}*/
} else if (entity.GetComponentInParent<BaseOven>() != null) {
var deploy = entity.GetComponentInParent<Deployable>();
var name = StringPool.Get(deploy.prefabID).ToString();
if (name=="items/furnace_deployed") {
var instanceId = OvenId(entity.GetComponentInParent<BaseOven>());
if (FurnaceConfig.ContainsKey(instanceId)) {
FurnaceConfig.Remove(instanceId);
}
}
}
}
public void OnGather(ResourceDispenser dispenser, BaseEntity entity, Item item)
{
BasePlayer player = entity.ToPlayer();
var type = dispenser.gatherType.ToString();
string weapon = player.svActiveItem.info.shortname;
if (type!="Flesh") {
if(!CorrectResources.ContainsKey(type)) {
return;
}
if(!CorrectResources[type].Exists(e => e.EndsWith(weapon))) {
if (ShowMessage(player,weapon,true)) ChatMessage(player, "<color='#00DD00'>Прогресс обучения:</color>\n<color='#FF0000'>Обучение невозможно - не верный ресурс!</color>");
return;
}
}
var skull = false;
if (item.info.shortname=="skull_human" || item.info.shortname=="skull_wolf") skull = true;
var meleeItem = player.svActiveItem.GetHeldEntity() as BaseMelee;
var cond = meleeItem.GetGatherInfoFromIndex(dispenser.gatherType);
if (weapon=="knife_bone"&&type=="Flesh"&&!skull) {
cond.conditionLost = 0.33f;
item.amount *= 2;
//player.svActiveItem.condition -= 0.33f;
}
var ret = CalcAction(player,"Gather",new Dictionary<string, object>(){
{"Type",type},
{"ItemAmount",item.amount},
{"Weapon",weapon},
{"WeaponObj",player.svActiveItem},
{"PlayerProf",true},
//{"ConditionLost",cond.conditionLost}
});
if (ret==null) return;
//item.amount += (int)Math.Round(item.amount*(1+(AmMul*WeaponSkill.Level))-item.amount*2);
//Print(item.info.shortname.ToString());
if (((float)ret["totalamount"]>0||StartGatherX!=1f) && !skull) {
item.amount = (int)Math.Round(item.amount*(1+StudyGetType(PlayerInfo(player),"total",0f,player))*(1+(float)ret["totalamount"])*StartGatherX);
}
var clangather = PluginInstance.GetClanBonus(SteamId(player),"gather");
var isvip = PluginInstance.IsVIP(player);
if (!skull && (isvip || clangather>0f)) {
var mul = (isvip?1.25f:1f);
if (clangather>0f) mul += clangather;
item.amount = (int)Math.Round(mul*item.amount);
}
/*if (player.svActiveItem.condition>0f && (float)ret["totalamount"]>0) {
player.svActiveItem.condition += cond.conditionLost*(float)ret["totalamount"];
}*/
}
private bool CanAffordUpgrade(int grade, BuildingBlock buildingBlock, BasePlayer player, float amount)
{
bool flag = true;
List<ItemAmount>.Enumerator enumerator = buildingBlock.blockDefinition.grades[(int)buildingBlock.grade].costToBuild.GetEnumerator(); //this[iGrade].costToBuild.GetEnumerator();
/*try
{*/
Dictionary<int,float> costs = new Dictionary<int,float>();
while (enumerator.MoveNext())
{
ItemAmount current = enumerator.Current;
var calc = (int)Math.Ceiling(current.amount*amount);
costs[current.itemid] = current.amount-calc;
}
enumerator = buildingBlock.blockDefinition.grades[grade].costToBuild.GetEnumerator();
while (enumerator.MoveNext())
{
ItemAmount current = enumerator.Current;
var calc = (int)Math.Ceiling(current.amount*amount);
var cost = 0f;
if (costs.ContainsKey(current.itemid)) {
cost = costs[current.itemid];
costs.Remove(current.itemid);
}
if (player.inventory.GetAmount(current.itemid) >= current.amount-calc+cost)
{
continue;
}
flag = false;
return flag;
}
if (costs.Count>0) {
foreach(KeyValuePair<int,float> kvp in costs) {
if (player.inventory.GetAmount(kvp.Key) >= kvp.Value) {
continue;
}
flag = false;
return flag;
}
}
//return true;
/*}
finally
{
((IDisposable)(object)enumerator).Dispose();
}*/
return flag;
}
public void OnEntityBuilt(Planner planner, UnityEngine.GameObject gameObject)
{
var addxp = 5;
BuildingBlock buildingBlock = gameObject.GetComponent<BuildingBlock>();
if (buildingBlock==null) return;
var items = buildingBlock.blockDefinition.grades[(int)buildingBlock.grade].costToBuild;
int amount = 0;
var player = planner.ownerPlayer;
var playerInfo = PlayerInfo(player);
if (playerInfo.PlayerSkills.ContainsKey("Build")) {
//List<Item> items2 = new List<Item>();
var level = playerInfo.PlayerSkills["Build"].Info.Level;
if (level>0) {
var calc = (1-(float)(StudyProfs["Build"].Skills["Build"].Mul))/SkillLvlTable.Count*level*(1+StudyGetType(playerInfo,"total",0f,player));
var grade = PlayerTmp(player).BuildGrade;
if (grade>0&&grade>(int)buildingBlock.grade&&buildingBlock.blockDefinition.grades[grade]) {
if (!CanAffordUpgrade(grade,buildingBlock,player,calc)) {
foreach (ItemAmount itemAmount in items)
{
player.inventory.GiveItem(itemAmount.itemid,(int)itemAmount.amount);
}
gameObject.GetComponent<BaseEntity>().KillMessage();
ChatMessage(player,"Недостаточно ресурсов для постройки.");
return;
} else {
var grd = (BuildingGrade.Enum) grade;
buildingBlock.SetGrade(grd);
buildingBlock.SetHealthToMax();
addxp = grade*30+5;
var items2 = buildingBlock.blockDefinition.grades[grade].costToBuild;
List<Item> items3 = new List<Item>();
foreach (ItemAmount itemAmount in items2)
{
amount = (int)Math.Ceiling(itemAmount.amount-(int)Math.Ceiling(itemAmount.amount*calc));
player.inventory.Take(items3, itemAmount.itemid, amount);
player.Command(string.Concat(new object[] { "note.inv ", itemAmount.itemid, " ", amount * -1f }), new object[0]);
}
}
}
foreach (ItemAmount itemAmount in items)
{
amount = (int)Math.Ceiling(itemAmount.amount*calc);
//planner.ownerPlayer.inventory.Take(items2, itemAmount.itemid, amount);
//planner.ownerPlayer.Command(string.Concat(new object[] { "note.inv ", itemAmount.itemid, " ", amount * -1f }), new object[0]);
player.inventory.GiveItem(itemAmount.itemid,amount);
}
}
}
var ret = CalcAction(player,"Build",new Dictionary<string, object>(){
{"Type","Build"},
{"ItemAmount",addxp},
{"PlayerProf",true},
//{"ConditionLost",1f}
});
}
public void OnBuildingBlockUpgrade(BuildingBlock buildingBlock, BasePlayer player, BuildingGrade.Enum grade)
{
var ret = CalcAction(player,"Upgrade",new Dictionary<string, object>(){
{"Type","Build"},
{"ItemAmount",(int)grade*30},
{"PlayerProf",true},
//{"ConditionLost",1f}
});
var items = buildingBlock.blockDefinition.grades[(int)grade].costToBuild;
int amount = 0;
//List<Item> items2 = new List<Item>();
var level = PlayerInfo(player).PlayerSkills["Build"].Info.Level;
if (level>0) {
foreach (ItemAmount itemAmount in items)
{
amount = (int)Math.Ceiling(itemAmount.amount*(1-(float)(StudyProfs["Build"].Skills["Build"].Mul))/SkillLvlTable.Count*level*(1+StudyGetType(PlayerInfo(player),"total",0f,player)));
//planner.ownerPlayer.inventory.Take(items2, itemAmount.itemid, amount);
//planner.ownerPlayer.Command(string.Concat(new object[] { "note.inv ", itemAmount.itemid, " ", amount * -1f }), new object[0]);
player.inventory.GiveItem(itemAmount.itemid,amount);
}
}
}
private Dictionary<string, object> CalcAction(BasePlayer player, string action, Dictionary<string, object> args) {
var playerInfo = PlayerInfo(player);
//string steamId = SteamId(player);
var type = (string)args["Type"];
var weapon = "null";
Item weaponObj = null;
if (args.ContainsKey("Weapon")) weapon = (string)args["Weapon"];
if (args.ContainsKey("WeaponObj")) weaponObj = (Item)args["WeaponObj"];
var IsUp = false;
var IsMax = false;
var ret = new Dictionary<string, object>();
var chatmsg = "";
var chatmsgevent = "";
ret["totalamount"] = 0f;
//ret["totalcond"] = 0f;
var AddXP = 0f;
if (args.ContainsKey("PlayerProf")) {
if(StudyProfs.ContainsKey(type)) {
var skill = StudyProfs[type];
AddXP = 0.5f;
if (args.ContainsKey("AddProfXP")) {
AddXP = (float)args["AddProfXP"];
} else if (weapon!="rock") {
AddXP = (int)args["ItemAmount"]/skill.Div;
}
var playerProf = CalcLvl(player,playerInfo,action,"Prof",AddXP,type,skill.Name[0],skill);
if (playerProf.chatmsg!="") chatmsg += playerProf.chatmsg + "\n";
//ret["SkillXPPerc"] = playerSkill.XPPerc;
if (playerProf.IsUp) IsUp = true;
if (IsMax) IsMax = true;
ret["totalamount"] = (float)ret["totalamount"]+playerProf.amount;
//ret["totalcond"] = (float)ret["totalcond"]+playerProf.cond;
ret["PlayerProf"] = playerProf;
if (playerProf.IsUp && StudyEvents.ContainsKey(type) && StudyEvents[type].ContainsKey(playerInfo.PlayerSkills[type].Info.Level)) {
if (chatmsgevent!="") chatmsgevent += "\n";
chatmsgevent += StudyEvents[type][playerInfo.PlayerSkills[type].Info.Level];
}
}
}
if (weapon!="null") {
AddXP = 1f;
if (args.ContainsKey("AddXP")) {
AddXP = (float)args["AddXP"];
} else if (type=="Flesh"&&weapon!="rock") {
AddXP = 5f;
}
var weaponSkill = CalcLvl(player,playerInfo,action,"Weapon",AddXP,weapon,weaponObj.info.displayName.translated);
chatmsg += weaponSkill.chatmsg;
if (weaponSkill.IsUp) IsUp = true;
if (weaponSkill.IsMax && (!ret.ContainsKey("PlayerProf") || ((CalcLvlRet)ret["PlayerProf"]).IsMax)) IsMax = true;
//ret["totalamount"] = (float)ret["totalamount"]+weaponSkill.amount;
//ret["totalcond"] = (float)ret["totalcond"]+weaponSkill.cond;
ret["WeaponSkill"] = weaponSkill;
}
if (IsUp) {
AddXP = 0f;
if (ret.ContainsKey("WeaponSkill")?((CalcLvlRet)ret["WeaponSkill"]).IsUp:false) AddXP += 5f;
if (ret.ContainsKey("PlayerProf")?((CalcLvlRet)ret["PlayerProf"]).IsUp:false) AddXP += 5f;
var playerLvl = CalcLvl(player,playerInfo,action,"Player",AddXP);
chatmsg = playerLvl.chatmsg + chatmsg;
if (playerLvl.IsUp && StudyEvents["playerlvl"].ContainsKey(playerInfo.Info.Level)) {
if (chatmsgevent!="") chatmsgevent += "\n";
chatmsgevent += StudyEvents["playerlvl"][playerInfo.Info.Level];
}
}
if (chatmsgevent!="") {
chatmsg += "\n<color='#DD0000'>Достижения:</color>\n"+chatmsgevent;
}
var showmsg = true;
if (playerInfo.MsgMode==2) showmsg = false;
else if (playerInfo.MsgMode==1 && !IsUp) showmsg = false;
if (chatmsg!="" && showmsg && ShowMessage(player,weapon,false,(ret.ContainsKey("WeaponSkill")?((CalcLvlRet)ret["WeaponSkill"]).XPPerc:0),(ret.ContainsKey("PlayerProf")?((CalcLvlRet)ret["PlayerProf"]).XPPerc:0),IsUp,IsMax)) {
/*var meleeItem = player.svActiveItem.GetHeldEntity() as BaseMelee;
float cond = 0f;
if (action=="Gather") cond = (float)args["ConditionLost"];
var xcond = (float)ret["totalcond"];
if (float.IsNaN(xcond)) xcond = 1;
decimal TotalX = 0;
if (action=="Gather") TotalX = (decimal)Math.Round((1+(((float)ret["totalamount"])*StartGatherX)/(int)args["ItemAmount"])*StartG
// ... [Code preview truncated due to length. Full source in attached file] ...