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

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman Plotnikov committed Apr 4, 2020
0 parents commit 0c3a2b4
Show file tree
Hide file tree
Showing 6 changed files with 410 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.suo
/.vs
/bin
/obj
/pdbs
/PreventEscapeSubModule.sln.DotSettings.user
/PreventEscape.csproj.user
/Win64_Shipping_Client
174 changes: 174 additions & 0 deletions PreventEscape.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D701D5AA-D88A-4025-A871-791A0F47852D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PreventEscape</RootNamespace>
<AssemblyName>PreventEscape</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="SandBox">
<HintPath>D:\GAMES\Steam\SteamApps\common\Mount &amp; Blade II Bannerlord\Modules\SandBox\bin\Win64_Shipping_Client\SandBox.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="TaleWorlds.BattlEye.Client">
<HintPath>Win64_Shipping_Client\TaleWorlds.BattlEye.Client.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.CampaignSystem">
<HintPath>Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.CampaignSystem.ViewModelCollection">
<HintPath>Win64_Shipping_Client\TaleWorlds.CampaignSystem.ViewModelCollection.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Core">
<HintPath>Win64_Shipping_Client\TaleWorlds.Core.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Core.ViewModelCollection">
<HintPath>Win64_Shipping_Client\TaleWorlds.Core.ViewModelCollection.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Diamond">
<HintPath>Win64_Shipping_Client\TaleWorlds.Diamond.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Diamond.AccessProvider.Epic">
<HintPath>Win64_Shipping_Client\TaleWorlds.Diamond.AccessProvider.Epic.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Diamond.AccessProvider.Steam">
<HintPath>Win64_Shipping_Client\TaleWorlds.Diamond.AccessProvider.Steam.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Diamond.AccessProvider.Test">
<HintPath>Win64_Shipping_Client\TaleWorlds.Diamond.AccessProvider.Test.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.DotNet">
<HintPath>Win64_Shipping_Client\TaleWorlds.DotNet.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.DotNet.AutoGenerated">
<HintPath>Win64_Shipping_Client\TaleWorlds.DotNet.AutoGenerated.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Engine">
<HintPath>Win64_Shipping_Client\TaleWorlds.Engine.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Engine.AutoGenerated">
<HintPath>Win64_Shipping_Client\TaleWorlds.Engine.AutoGenerated.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Engine.GauntletUI">
<HintPath>Win64_Shipping_Client\TaleWorlds.Engine.GauntletUI.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.GauntletUI">
<HintPath>Win64_Shipping_Client\TaleWorlds.GauntletUI.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.GauntletUI.Data">
<HintPath>Win64_Shipping_Client\TaleWorlds.GauntletUI.Data.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.GauntletUI.ExtraWidgets">
<HintPath>Win64_Shipping_Client\TaleWorlds.GauntletUI.ExtraWidgets.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.GauntletUI.PrefabSystem">
<HintPath>Win64_Shipping_Client\TaleWorlds.GauntletUI.PrefabSystem.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.GauntletUI.TooltipExtensions">
<HintPath>Win64_Shipping_Client\TaleWorlds.GauntletUI.TooltipExtensions.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.InputSystem">
<HintPath>Win64_Shipping_Client\TaleWorlds.InputSystem.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Library">
<HintPath>Win64_Shipping_Client\TaleWorlds.Library.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Localization">
<HintPath>Win64_Shipping_Client\TaleWorlds.Localization.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.MountAndBlade">
<HintPath>Win64_Shipping_Client\TaleWorlds.MountAndBlade.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.MountAndBlade.AutoGenerated">
<HintPath>Win64_Shipping_Client\TaleWorlds.MountAndBlade.AutoGenerated.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.MountAndBlade.Diamond">
<HintPath>Win64_Shipping_Client\TaleWorlds.MountAndBlade.Diamond.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.MountAndBlade.GauntletUI.Widgets">
<HintPath>Win64_Shipping_Client\TaleWorlds.MountAndBlade.GauntletUI.Widgets.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.MountAndBlade.Helpers">
<HintPath>Win64_Shipping_Client\TaleWorlds.MountAndBlade.Helpers.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.MountAndBlade.ViewModelCollection">
<HintPath>Win64_Shipping_Client\TaleWorlds.MountAndBlade.ViewModelCollection.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.NavigationSystem">
<HintPath>Win64_Shipping_Client\TaleWorlds.NavigationSystem.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Network">
<HintPath>Win64_Shipping_Client\TaleWorlds.Network.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.PlatformService">
<HintPath>Win64_Shipping_Client\TaleWorlds.PlatformService.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.PlatformService.Epic">
<HintPath>Win64_Shipping_Client\TaleWorlds.PlatformService.Epic.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.PlatformService.Steam">
<HintPath>Win64_Shipping_Client\TaleWorlds.PlatformService.Steam.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.PlayerServices">
<HintPath>Win64_Shipping_Client\TaleWorlds.PlayerServices.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.PSAI">
<HintPath>Win64_Shipping_Client\TaleWorlds.PSAI.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.SaveSystem">
<HintPath>Win64_Shipping_Client\TaleWorlds.SaveSystem.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Starter.DotNetCore">
<HintPath>Win64_Shipping_Client\TaleWorlds.Starter.DotNetCore.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.Starter.Library">
<HintPath>Win64_Shipping_Client\TaleWorlds.Starter.Library.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.TwoDimension">
<HintPath>Win64_Shipping_Client\TaleWorlds.TwoDimension.dll</HintPath>
</Reference>
<Reference Include="TaleWorlds.TwoDimension.Standalone">
<HintPath>Win64_Shipping_Client\TaleWorlds.TwoDimension.Standalone.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="PreventEscapeSubModule.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="SubModule.xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
127 changes: 127 additions & 0 deletions PreventEscapeSubModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.Barterables;
using TaleWorlds.CampaignSystem.SandBox.CampaignBehaviors;
using TaleWorlds.CampaignSystem.SandBox.CampaignBehaviors.BarterBehaviors;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.MountAndBlade;

namespace PreventEscape
{
public class PreventEscapeSubModule : MBSubModuleBase
{
public static double BaseEscapeChance = 0.01;
public static double BaseEscapeChanceFromBandits = 0.1;
public static double EscapeFromPlayerModifier = 0.33;
public static double AtWarModifier = 0.1;
protected override void OnSubModuleLoad()
{
var path = BasePath.Name + "Modules/PreventEscape/SubModule.xml";
if (File.Exists(path))
{
try
{
var doc = new XmlDocument();
using (var stringReader = new System.IO.StringReader(File.ReadAllText(path)))
using (var xmlReader = XmlReader.Create(stringReader))
doc.Load(xmlReader);
XmlNode mainNode = doc.SelectSingleNode("/Module/Config");
if (mainNode != null)
{
if (!double.TryParse(mainNode["BaseEscapeChance"]?.InnerText ?? "", out BaseEscapeChance))
BaseEscapeChance = 0.01;
if (!double.TryParse(mainNode["BaseEscapeChanceFromBandits"]?.InnerText ?? "", out BaseEscapeChanceFromBandits))
BaseEscapeChanceFromBandits = 0.1;
if (!double.TryParse(mainNode["EscapeFromPlayerModifier"]?.InnerText ?? "", out EscapeFromPlayerModifier))
EscapeFromPlayerModifier = 0.33;
if (!double.TryParse(mainNode["AtWarModifier"]?.InnerText ?? "", out AtWarModifier))
AtWarModifier = 0.1;
}
}
catch
{
BaseEscapeChance = 0.01;
BaseEscapeChanceFromBandits = 0.1;
EscapeFromPlayerModifier = 0.33;
AtWarModifier = 0.1;
}
}
}
public override bool DoLoading(Game game)
{
if (Campaign.Current == null)
return true;
var prisonerEscapeBehaviour = Campaign.Current.GetCampaignBehavior<PrisonerEscapeCampaignBehavior>();
var barterBehaviour = Campaign.Current.GetCampaignBehavior<DiplomaticBartersBehavior>();
var originalPrisonerEscapeHeroTick = prisonerEscapeBehaviour != null ? new Action<Hero>(prisonerEscapeBehaviour.DailyHeroTick) : null;
var originalBarterHeroTickMethodInfo = typeof(DiplomaticBartersBehavior).GetMethod("DailyTickHero", BindingFlags.NonPublic | BindingFlags.Instance);
var originalBarterHeroTick = originalBarterHeroTickMethodInfo != null ? (Action<Hero>)Delegate.CreateDelegate(typeof(Action<Hero>), barterBehaviour, originalBarterHeroTickMethodInfo) : null;
if (CampaignEvents.DailyTickHeroEvent == null)
return true;
CampaignEvents.DailyTickHeroEvent.ClearListeners(prisonerEscapeBehaviour);
CampaignEvents.DailyTickHeroEvent.ClearListeners(barterBehaviour);
CampaignEvents.DailyTickHeroEvent.AddNonSerializedListener(prisonerEscapeBehaviour, hero => PrisonerEscapeHeroDailyTickWrapper(hero, originalPrisonerEscapeHeroTick));
CampaignEvents.DailyTickHeroEvent.AddNonSerializedListener(prisonerEscapeBehaviour, hero => BarterDailyTickHeroWrapper(hero, originalBarterHeroTick));
return base.DoLoading(game);
}
private void BarterDailyTickHeroWrapper(Hero hero, Action<Hero> originalBehavior)
{
try
{
if (!hero.IsPrisoner || hero.Clan == null || (hero.PartyBelongedToAsPrisoner == null || (double)MBRandom.RandomFloat >= 0.100000001490116))
return;
var captorParty = hero.PartyBelongedToAsPrisoner;
var captorFaction = captorParty.MapFaction;
var offerer = hero.Clan.Leader;
var captorLeader = captorFaction.Leader;
var prisonerClan = hero.Clan;
SetPrisonerFreeBarterable prisonerFreeBarterable = new SetPrisonerFreeBarterable(hero, captorLeader, captorParty, offerer);
if (prisonerFreeBarterable.GetValueForFaction(captorFaction) + prisonerFreeBarterable.GetValueForFaction(prisonerClan) <= 0)
return;
if (captorFaction.IsBanditFaction)
{
BarterData barterData = new BarterData(hero.Clan.Leader, captorFaction.Leader, (PartyBase)null, (PartyBase)null,
(BarterManager.BarterContextInitializer)null, 0, true);
barterData.AddBarterable<DefaultsBarterGroup>(prisonerFreeBarterable);
Campaign.Current.BarterManager.ExecuteAIBarter(barterData, captorFaction, hero.Clan, captorFaction.Leader, hero.Clan.Leader);
}
}
catch (Exception e)
{
if (originalBehavior != null)
originalBehavior(hero);
}
}
private void PrisonerEscapeHeroDailyTickWrapper(Hero hero, Action<Hero> originalBehavior)
{
try
{
if (!hero.IsPrisoner || hero.PartyBelongedToAsPrisoner == null || hero == Hero.MainHero)
return;
double chance = hero.PartyBelongedToAsPrisoner.MapFaction.IsBanditFaction ? BaseEscapeChanceFromBandits : BaseEscapeChance;
if (hero.PartyBelongedToAsPrisoner.IsMobile)
chance *= 6 - Math.Pow(hero.PartyBelongedToAsPrisoner.NumberOfHealthyMembers, 0.25);
if (hero.PartyBelongedToAsPrisoner.MapFaction == Hero.MainHero.MapFaction)
chance *= EscapeFromPlayerModifier;
if (hero.MapFaction.IsAtWarWith(hero.PartyBelongedToAsPrisoner.MapFaction))
chance *= AtWarModifier;
if (MBRandom.RandomFloat >= chance)
return;
EndCaptivityAction.ApplyByEscape(hero, (Hero)null);
}
catch (Exception exception)
{
if (originalBehavior != null)
originalBehavior(hero);
}
}
}
}
25 changes: 25 additions & 0 deletions PreventEscapeSubModule.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29215.179
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PreventEscape", "PreventEscape.csproj", "{D701D5AA-D88A-4025-A871-791A0F47852D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D701D5AA-D88A-4025-A871-791A0F47852D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D701D5AA-D88A-4025-A871-791A0F47852D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D701D5AA-D88A-4025-A871-791A0F47852D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D701D5AA-D88A-4025-A871-791A0F47852D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AB2607B3-7483-4832-A8E9-9996E5533B0A}
EndGlobalSection
EndGlobal
36 changes: 36 additions & 0 deletions Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("PreventEscapeSubModule")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PreventEscapeSubModule")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("d701d5aa-d88a-4025-a871-791a0f47852d")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Loading

0 comments on commit 0c3a2b4

Please sign in to comment.