VS plugin mod for Basic Armour
Révision | e6d94c3df3c8d8fd09592894f3abfe8f15d8469f (tree) |
---|---|
l'heure | 2019-05-18 06:37:16 |
Auteur | ![]() |
Commiter | melchior |
Pushed server side config
refactorings
@@ -0,0 +1,17 @@ | ||
1 | +using System; | |
2 | + | |
3 | +namespace ArmourMod | |
4 | +{ | |
5 | + | |
6 | + internal class ArmourModConfig | |
7 | + { | |
8 | + public bool DropArmourOnDeath { get; set; } | |
9 | + | |
10 | + public ArmourModConfig( ) | |
11 | + { | |
12 | + this.DropArmourOnDeath = false; | |
13 | + | |
14 | + } | |
15 | + } | |
16 | +} | |
17 | + |
@@ -2,7 +2,7 @@ | ||
2 | 2 | using System.Collections.Generic; |
3 | 3 | using System.Linq; |
4 | 4 | using System.Text; |
5 | -using System.Threading.Tasks; | |
5 | + | |
6 | 6 | |
7 | 7 | using Vintagestory.API; |
8 | 8 | using Vintagestory.API.Common; |
@@ -18,8 +18,42 @@ namespace ArmourMod | ||
18 | 18 | { |
19 | 19 | public class ArmourModHookin: ModSystem |
20 | 20 | { |
21 | - private static string _domain = @"armourmod"; | |
22 | - private static string _thirdPersonKey = @"thirdPersonTransform"; | |
21 | + internal const string _domain = @"armourmod"; | |
22 | + private const string _thirdPersonKey = @"thirdPersonTransform"; | |
23 | + internal const string _configFilename = @"armourmod.json"; | |
24 | + | |
25 | + private ICoreServerAPI ServerAPI; | |
26 | + private ICoreClientAPI ClientAPI; | |
27 | + private ICoreAPI CoreAPI; | |
28 | + private IServerNetworkChannel _sendConfigChannel; | |
29 | + private IClientNetworkChannel _receiveConfigChannel; | |
30 | + | |
31 | + /// <summary> | |
32 | + /// Gets or sets the cached configuration. | |
33 | + /// </summary> | |
34 | + /// <value>The cached configuration.</value> | |
35 | + /// <remarks>Used BOTH "SIDES", switch implimentation automatically.</remarks> | |
36 | + internal ArmourModConfig CachedConfiguration | |
37 | + { | |
38 | + get | |
39 | + { | |
40 | + if (CoreAPI.Side.IsServer( )) { | |
41 | + return ( ArmourModConfig )ServerAPI.ObjectCache[_configFilename]; | |
42 | + } else { | |
43 | + return ( ArmourModConfig )ClientAPI.ObjectCache[_configFilename]; | |
44 | + } | |
45 | + | |
46 | + } | |
47 | + set { | |
48 | + | |
49 | + if (CoreAPI.Side.IsServer( )) { | |
50 | + ServerAPI.ObjectCache.Add(_configFilename, value); | |
51 | + } else { | |
52 | + ClientAPI.ObjectCache.Add(_configFilename, value); | |
53 | + } | |
54 | + } | |
55 | + } | |
56 | + | |
23 | 57 | |
24 | 58 | public override double ExecuteOrder() |
25 | 59 | { |
@@ -40,29 +74,103 @@ namespace ArmourMod | ||
40 | 74 | { |
41 | 75 | //Both Server parts and Client part(s) |
42 | 76 | base.Start(api); |
77 | + this.CoreAPI = api; | |
43 | 78 | var entityPlayerClassName = api.ClassRegistry.GetEntityClassName( typeof(EntityPlayer) ); |
44 | 79 | api.RegisterEntity( entityPlayerClassName, typeof(EntityArmourPlayer) );// class swap 'EntityPlayer' |
45 | - api.World.Logger.Debug("Replaced EntityPlayer with Armour version"); | |
80 | + Mod.Logger.Notification("Replaced EntityPlayer with Armour version"); | |
81 | + } | |
82 | + | |
83 | + public override void StartServerSide(ICoreServerAPI api) | |
84 | + { | |
85 | + base.StartServerSide(api); | |
86 | + | |
87 | + this.ServerAPI = api; | |
88 | + | |
89 | + PrepareServersideConfig( ); | |
46 | 90 | } |
47 | 91 | |
48 | 92 | public override void StartClientSide(ICoreClientAPI ClientApi) |
49 | - { | |
93 | + { | |
94 | + this.ClientAPI = ClientApi; | |
50 | 95 | ClientApi.Event.BlockTexturesLoaded += () => { |
51 | - ClientApi.Logger.VerboseDebug( "Armour Mod Populate Armoury, Attach Renderers " ); | |
96 | + #if DEBUG | |
97 | + Mod.Logger.VerboseDebug( "Armour Mod Populate Armoury, Attach Renderers " ); | |
98 | + #endif | |
52 | 99 | |
53 | 100 | var armorData = PopulateArmoury( ClientApi ); |
54 | 101 | ArmourMeshRenderer theOne = new ArmourMeshRenderer(ClientApi, armorData ); |
55 | 102 | |
56 | 103 | //#if RENDER |
57 | - ClientApi.Logger.VerboseDebug( "Registering Renderers for Armour"); | |
104 | + Mod.Logger.VerboseDebug( "Registering Renderers for Armour"); | |
58 | 105 | ClientApi.Event.RegisterRenderer(theOne, EnumRenderStage.Opaque,this.Mod.Info.Name); |
59 | 106 | ClientApi.Event.RegisterRenderer(theOne, EnumRenderStage.ShadowFar,this.Mod.Info.Name); |
60 | 107 | ClientApi.Event.RegisterRenderer(theOne, EnumRenderStage.ShadowNear,this.Mod.Info.Name); |
61 | 108 | //#endif |
62 | 109 | }; |
63 | 110 | |
111 | + ListenForServerConfigMessage( ); | |
64 | 112 | } |
65 | 113 | |
114 | + #region Configuration Synch-up | |
115 | + | |
116 | + private void PrepareServersideConfig( ) | |
117 | + { | |
118 | + ArmourModConfig config = ServerAPI.LoadModConfig<ArmourModConfig>(_configFilename); | |
119 | + | |
120 | + if (config == null) { | |
121 | + //Regen default | |
122 | + Mod.Logger.Warning("Regenerating default config as it was missing / unparsable..."); | |
123 | + ServerAPI.StoreModConfig<ArmourModConfig>(new ArmourModConfig(), _configFilename); | |
124 | + config = ServerAPI.LoadModConfig<ArmourModConfig>(_configFilename); | |
125 | + } | |
126 | + | |
127 | + this.CachedConfiguration = config; | |
128 | + | |
129 | + //Setup channel for future use. | |
130 | + _sendConfigChannel = ServerAPI.Network.RegisterChannel(_domain); | |
131 | + _sendConfigChannel = _sendConfigChannel.RegisterMessageType<ArmourModConfig>( ); | |
132 | + | |
133 | + //Attach event upon client join to send them a copy of config settings | |
134 | + ServerAPI.Event.PlayerJoin += SendJoinerConfigMessage; | |
135 | + } | |
136 | + | |
137 | + private void SendJoinerConfigMessage(IServerPlayer byPlayer) | |
138 | + { | |
139 | + #if DEBUG | |
140 | + Mod.Logger.VerboseDebug("Sending joiner: {0} a copy of config data.", byPlayer.PlayerName); | |
141 | + #endif | |
142 | + | |
143 | + this._sendConfigChannel.SendPacket<ArmourModConfig>(this.CachedConfiguration, byPlayer); | |
144 | + } | |
145 | + | |
146 | + private void ListenForServerConfigMessage( ) | |
147 | + { | |
148 | + _receiveConfigChannel = ClientAPI.Network.RegisterChannel(_domain); | |
149 | + _receiveConfigChannel = _receiveConfigChannel.RegisterMessageType<ArmourModConfig>( ); | |
150 | + | |
151 | + #if DEBUG | |
152 | + Mod.Logger.VerboseDebug("Registered RX channel: '{0}'", _receiveConfigChannel.ChannelName); | |
153 | + #endif | |
154 | + | |
155 | + _receiveConfigChannel.SetMessageHandler<ArmourModConfig>(RecievedConfigMessage); | |
156 | + } | |
157 | + | |
158 | + private void RecievedConfigMessage(ArmourModConfig networkMessage) | |
159 | + { | |
160 | + #if DEBUG | |
161 | + Mod.Logger.Debug("RX Config message!"); | |
162 | + #endif | |
163 | + | |
164 | + if (networkMessage != null) { | |
165 | + Mod.Logger.Debug("Message value; DropArmourOnDeath = {0}",networkMessage.DropArmourOnDeath); | |
166 | + this.CachedConfiguration = networkMessage; | |
167 | + } | |
168 | + } | |
169 | + | |
170 | + #endregion | |
171 | + | |
172 | + | |
173 | + | |
66 | 174 | /// <summary> |
67 | 175 | /// Populates the Cached data for Rendering. |
68 | 176 | /// </summary> |
@@ -2,10 +2,12 @@ | ||
2 | 2 | using System.Collections.Generic; |
3 | 3 | using System.Linq; |
4 | 4 | |
5 | + | |
5 | 6 | using Vintagestory.API.Common; |
6 | 7 | using Vintagestory.API.Client; |
7 | 8 | using Vintagestory.API.Server; |
8 | - | |
9 | + | |
10 | + | |
9 | 11 | namespace ArmourMod |
10 | 12 | { |
11 | 13 | public class EntityArmourPlayer : EntityPlayer |
@@ -16,15 +18,23 @@ namespace ArmourMod | ||
16 | 18 | protected ILogger Logger; |
17 | 19 | |
18 | 20 | //Damage Filter list: BY Inventory SLOT# |
19 | - private Dictionary<int,DamageFilter> DamageFilters; | |
20 | - //Pre-cook values: Covert to Coalesced filter sooon! | |
21 | - private float bluntPercentReduction = 0F; | |
22 | - private float piercingPercentReduction = 0F; | |
23 | - private float slashingPercentReduction = 0F; | |
24 | - private float crushingPercentReduction = 0F; | |
25 | - private float firePercentReduction = 0F; | |
21 | + private Dictionary<EnumCharacterDressType,DamageFilter> DamageFilters; | |
26 | 22 | |
27 | - //private long client_callback; | |
23 | + //Pre-compute values; | |
24 | + private DamageFilter finalFilter; | |
25 | + | |
26 | + internal ArmourModConfig CachedConfiguration | |
27 | + { | |
28 | + get | |
29 | + { | |
30 | + if (CoreAPI.Side.IsServer( )) { | |
31 | + return ( ArmourModConfig )ServerAPI.ObjectCache[ArmourModHookin._configFilename]; | |
32 | + } else { | |
33 | + return ( ArmourModConfig )ClientAPI.ObjectCache[ArmourModHookin._configFilename]; | |
34 | + } | |
35 | + | |
36 | + } | |
37 | + } | |
28 | 38 | |
29 | 39 | public Dictionary<EnumCharacterDressType,Item> RenderableWornArmours { get; private set;}//Needs to be client side |
30 | 40 |
@@ -43,8 +53,10 @@ namespace ArmourMod | ||
43 | 53 | } |
44 | 54 | |
45 | 55 | if (CoreAPI.Side.IsServer( )) { |
46 | - this.ServerAPI = api as ICoreServerAPI; | |
47 | - | |
56 | + this.ServerAPI = api as ICoreServerAPI; | |
57 | + //from Config set values; | |
58 | + //ServerAPI.ModLoader. | |
59 | + //ArmourModHookin._domain | |
48 | 60 | } |
49 | 61 | } |
50 | 62 |
@@ -63,7 +75,7 @@ namespace ArmourMod | ||
63 | 75 | #endif |
64 | 76 | |
65 | 77 | //base.GearInventory.SlotModified += ClientWatchSlotModified; |
66 | - ClientAPI.Event.PlayerJoin += ClientDelayHook; ; | |
78 | + ClientAPI.Event.PlayerJoin += ClientDelayHook; | |
67 | 79 | } |
68 | 80 | } |
69 | 81 |
@@ -94,18 +106,16 @@ namespace ArmourMod | ||
94 | 106 | { |
95 | 107 | base.Die( reason, damageSourceForDeath ); |
96 | 108 | |
97 | - bool loseArmourOnDeath = true; | |
98 | - | |
99 | 109 | //(Properties.Server?.Attributes?.GetBool("keepContents", false) != true) |
100 | 110 | // World.PlayerByUid(PlayerUID).InventoryManager.OnDeath(); |
101 | 111 | if ( CoreAPI.Side.IsServer( ) ) { |
102 | 112 | |
103 | - if ( loseArmourOnDeath ) { | |
113 | + if ( this.CachedConfiguration.DropArmourOnDeath ) { | |
104 | 114 | //Clear Armour filters; Drop Server side Armour Item, |
105 | 115 | |
106 | 116 | var invBase = this.GearInventory as InventoryBasePlayer; |
107 | 117 | if ( invBase != null ) { |
108 | - invBase.DropSlots( this.ServerPos.XYZ.Add( 0.5, 0.5, 0.5 ), this.DamageFilters.Keys.ToArray( ) ); | |
118 | + invBase.DropSlots( this.ServerPos.XYZ.Add( 0.5, 0.5, 0.5 ), this.DamageFilters.Keys.Select(key => (int)key).ToArray());; | |
109 | 119 | } else { |
110 | 120 | Logger.Error( "invBase NULL! - can't drop armour" ); |
111 | 121 | } |
@@ -117,7 +127,7 @@ namespace ArmourMod | ||
117 | 127 | |
118 | 128 | if ( CoreAPI.Side.IsClient() ) { |
119 | 129 | //clear client side entry too! |
120 | - if ( loseArmourOnDeath ) { | |
130 | + if ( this.CachedConfiguration.DropArmourOnDeath ) { | |
121 | 131 | |
122 | 132 | this.RenderableWornArmours.Clear( ); |
123 | 133 | } |
@@ -156,23 +166,23 @@ namespace ArmourMod | ||
156 | 166 | switch (damageSource.Type) { |
157 | 167 | |
158 | 168 | case EnumDamageType.BluntAttack: |
159 | - damage -= damage * bluntPercentReduction; | |
169 | + damage -= damage * finalFilter.bluntPercent; | |
160 | 170 | break; |
161 | 171 | |
162 | 172 | case EnumDamageType.PiercingAttack: |
163 | - damage -= damage * piercingPercentReduction; | |
173 | + damage -= damage * finalFilter.piercingPercent; | |
164 | 174 | break; |
165 | 175 | |
166 | 176 | case EnumDamageType.SlashingAttack: |
167 | - damage -= damage * slashingPercentReduction; | |
177 | + damage -= damage * finalFilter.slashingPercent; | |
168 | 178 | break; |
169 | 179 | |
170 | 180 | case EnumDamageType.Crushing: |
171 | - damage -= damage * crushingPercentReduction; | |
181 | + damage -= damage * finalFilter.crushingPercent; | |
172 | 182 | break; |
173 | 183 | |
174 | 184 | case EnumDamageType.Fire: |
175 | - damage -= damage * firePercentReduction; | |
185 | + damage -= damage * finalFilter.firePercent; | |
176 | 186 | break; |
177 | 187 | |
178 | 188 | default: |
@@ -186,10 +196,10 @@ namespace ArmourMod | ||
186 | 196 | #endif |
187 | 197 | |
188 | 198 | //All worn Armours adsorb damage themselves... |
189 | - List<int> slotsList = this.DamageFilters.Keys.ToList(); | |
199 | + List<EnumCharacterDressType> slotsList = this.DamageFilters.Keys.ToList(); | |
190 | 200 | |
191 | 201 | foreach (var slotId in slotsList) { |
192 | - ItemSlot slot = this.GearInventory[slotId]; | |
202 | + ItemSlot slot = this.GearInventory[(int)slotId]; | |
193 | 203 | Item armourItem = slot.Itemstack.Item; |
194 | 204 | |
195 | 205 | armourItem.DamageItem(ServerAPI.World, damageSource.SourceEntity, slot, 1); |
@@ -266,14 +276,14 @@ namespace ArmourMod | ||
266 | 276 | |
267 | 277 | Logger.VerboseDebug( "Armour Filter Props: B{0} P{1} S{2} C{3} F{4}", dmgFilt.bluntPercent, dmgFilt.piercingPercent, dmgFilt.slashingPercent, dmgFilt.crushingPercent, dmgFilt.firePercent ); |
268 | 278 | |
269 | - DamageFilters[slotId] = dmgFilt; | |
279 | + DamageFilters[(EnumCharacterDressType)slotId] = dmgFilt; | |
270 | 280 | RecomputeDamageFilterPercents( ); |
271 | 281 | } |
272 | 282 | } |
273 | 283 | } else if (watchedSlot.StorageType == EnumItemStorageFlags.Outfit){ |
274 | 284 | //Clear out filters for what was in slot# X here - if applicable |
275 | 285 | Logger.VerboseDebug( "Removed a clothing item from SlotId:{0}",slotId ); |
276 | - DamageFilters.Remove( slotId ); | |
286 | + DamageFilters.Remove((EnumCharacterDressType)slotId); | |
277 | 287 | RecomputeDamageFilterPercents( ); |
278 | 288 | } |
279 | 289 | } |
@@ -310,12 +320,12 @@ namespace ArmourMod | ||
310 | 320 | |
311 | 321 | private void PopulateDamageFilters() |
312 | 322 | { |
313 | - DamageFilters = new Dictionary<int, DamageFilter>( 10 ); | |
323 | + DamageFilters = new Dictionary<EnumCharacterDressType, DamageFilter>( Enum.GetNames(typeof(EnumCharacterDressType)).Length ); | |
314 | 324 | |
315 | 325 | if ( this.GearInventory.Count > 0 ) { |
316 | 326 | foreach(var itemSlot in this.GearInventory ) { |
317 | 327 | |
318 | - int slotId = this.GearInventory.GetSlotId( itemSlot ); | |
328 | + EnumCharacterDressType slotId = (EnumCharacterDressType)this.GearInventory.GetSlotId( itemSlot ); | |
319 | 329 | if ( !itemSlot.Empty ) { |
320 | 330 | |
321 | 331 | if ( itemSlot.StorageType == EnumItemStorageFlags.Outfit && itemSlot.Itemstack.Class == EnumItemClass.Item ) { |
@@ -348,25 +358,25 @@ namespace ArmourMod | ||
348 | 358 | { |
349 | 359 | if (DamageFilters != null && DamageFilters.Count > 0) |
350 | 360 | { |
351 | - bluntPercentReduction = DamageFilters.Sum( df => df.Value.bluntPercent ); | |
352 | - bluntPercentReduction = Math.Abs( bluntPercentReduction ); | |
353 | - bluntPercentReduction = Math.Min( 0.95F, bluntPercentReduction ); | |
361 | + finalFilter.bluntPercent = DamageFilters.Sum( df => df.Value.bluntPercent ); | |
362 | + finalFilter.bluntPercent = Math.Abs( finalFilter.bluntPercent ); | |
363 | + finalFilter.bluntPercent = Math.Min( 0.95F, finalFilter.bluntPercent ); | |
354 | 364 | |
355 | - piercingPercentReduction = DamageFilters.Sum( df => df.Value.piercingPercent ); | |
356 | - piercingPercentReduction = Math.Abs( piercingPercentReduction ); | |
357 | - piercingPercentReduction = Math.Min( 0.95F, piercingPercentReduction ); | |
365 | + finalFilter.piercingPercent = DamageFilters.Sum( df => df.Value.piercingPercent ); | |
366 | + finalFilter.piercingPercent = Math.Abs( finalFilter.piercingPercent ); | |
367 | + finalFilter.piercingPercent = Math.Min( 0.95F, finalFilter.piercingPercent ); | |
358 | 368 | |
359 | - slashingPercentReduction = DamageFilters.Sum( df => df.Value.slashingPercent ); | |
360 | - slashingPercentReduction = Math.Abs( slashingPercentReduction ); | |
361 | - slashingPercentReduction = Math.Min( 0.95F, slashingPercentReduction ); | |
369 | + finalFilter.slashingPercent = DamageFilters.Sum( df => df.Value.slashingPercent ); | |
370 | + finalFilter.slashingPercent = Math.Abs( finalFilter.slashingPercent ); | |
371 | + finalFilter.slashingPercent = Math.Min( 0.95F, finalFilter.slashingPercent ); | |
362 | 372 | |
363 | - crushingPercentReduction = DamageFilters.Sum( df => df.Value.crushingPercent ); | |
364 | - crushingPercentReduction = Math.Abs( crushingPercentReduction ); | |
365 | - crushingPercentReduction = Math.Min( 0.95F, crushingPercentReduction ); | |
373 | + finalFilter.crushingPercent = DamageFilters.Sum( df => df.Value.crushingPercent ); | |
374 | + finalFilter.crushingPercent = Math.Abs( finalFilter.crushingPercent ); | |
375 | + finalFilter.crushingPercent = Math.Min( 0.95F, finalFilter.crushingPercent ); | |
366 | 376 | |
367 | - firePercentReduction = DamageFilters.Sum( df => df.Value.firePercent ); | |
368 | - firePercentReduction = Math.Abs( firePercentReduction ); | |
369 | - firePercentReduction = Math.Min( 0.95F, firePercentReduction ); | |
377 | + finalFilter.firePercent = DamageFilters.Sum( df => df.Value.firePercent ); | |
378 | + finalFilter.firePercent = Math.Abs( finalFilter.firePercent ); | |
379 | + finalFilter.firePercent = Math.Min( 0.95F, finalFilter.firePercent ); | |
370 | 380 | } |
371 | 381 | } |
372 | 382 |
@@ -61,6 +61,7 @@ | ||
61 | 61 | <Compile Include="Armour\EntityArmourPlayer.cs" /> |
62 | 62 | <Compile Include="Armour\AmourMeshRenderer.cs" /> |
63 | 63 | <Compile Include="Armour\ArmourModelData.cs" /> |
64 | + <Compile Include="Armour\ArmourModConfig.cs" /> | |
64 | 65 | </ItemGroup> |
65 | 66 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
66 | 67 | <ItemGroup> |
@@ -1,11 +1,15 @@ | ||
1 | - | |
2 | -{ | |
3 | - "armourmod:item-clothes-head-potmetal": "Metal Pot Helm", | |
4 | - "armourmod:item-clothes-upperbodyover-vest-studdedleather": "Studded Leather Vest", | |
5 | - "armourmod:item-clothes-upperbodyover-vest-scale": "Scale Mail Vest", | |
6 | - "armourmod:item-clothes-upperbodyover-vest-platechest": "Plate Armour Vest", | |
7 | - "armourmod:item-clothes-upperbodyover-vest-leather": "Leather Vest", | |
8 | - "armourmod:item-clothes-upperbodyover-vest-lamellar": "Lamellar Armour Vest", | |
9 | - "armourmod:item-clothes-upperbodyover-vest-coatofplates": "Coat'o'Plates Armour Vest", | |
10 | - "armourmod:item-clothes-upperbodyover-vest-chain": "Chainmail", | |
1 | +{ | |
2 | + "item:clothes-head-potmetal": "Metal Pot Helm", | |
3 | + "item:clothes-upperbodyover-vest-studdedleather": "Studded Leather Vest", | |
4 | + "item:clothes-upperbodyover-vest-scale": "Scale Mail Vest", | |
5 | + "item:clothes-upperbodyover-vest-platechest": "Plate Armour Vest", | |
6 | + "item:clothes-upperbodyover-vest-leather": "Leather Vest", | |
7 | + "item:clothes-upperbodyover-vest-lamellar": "Lamellar Armour Vest", | |
8 | + "item:clothes-upperbodyover-vest-coatofplates": "Coat'o'Plates Armour Vest", | |
9 | + "item:clothes-upperbodyover-vest-chain": "Chainmail" , | |
10 | + | |
11 | + "armourmod:item-clothes-upperbodyover-vest-leather": "2Leather Vest", | |
12 | + "armourmod:clothes-upperbodyover-vest-leather": "3Leather Vest", | |
13 | + "armourmod:item-upperbodyover-vest-leather": "4Leather Vest", | |
14 | + | |
11 | 15 | } |
\ No newline at end of file |