VS plugin mod for Basic Armour
Révision | fd5592b782601ff49a2fd861ea8da5cca36ad760 (tree) |
---|---|
l'heure | 2019-05-25 10:04:24 |
Auteur | ![]() |
Commiter | melchior |
Workaround for duplicated event registration from OnLoad call(s),
New tooltips for armour
@@ -21,6 +21,7 @@ namespace ArmourMod | ||
21 | 21 | internal const string _domain = @"armourmod"; |
22 | 22 | private const string _thirdPersonKey = @"thirdPersonTransform"; |
23 | 23 | internal const string _configFilename = @"armourmod.json"; |
24 | + private const string _itemArmourName = @"ItemArmour"; | |
24 | 25 | |
25 | 26 | private ICoreServerAPI ServerAPI; |
26 | 27 | private ICoreClientAPI ClientAPI; |
@@ -57,7 +58,7 @@ namespace ArmourMod | ||
57 | 58 | |
58 | 59 | public override double ExecuteOrder() |
59 | 60 | { |
60 | - return 1.1D; | |
61 | + return 0.19D; | |
61 | 62 | } |
62 | 63 | |
63 | 64 | public override bool AllowRuntimeReload |
@@ -76,6 +77,7 @@ namespace ArmourMod | ||
76 | 77 | base.Start(api); |
77 | 78 | this.CoreAPI = api; |
78 | 79 | |
80 | + api.RegisterItemClass(_itemArmourName, typeof(ItemArmour)); | |
79 | 81 | } |
80 | 82 | |
81 | 83 | public override void StartServerSide(ICoreServerAPI api) |
@@ -12,6 +12,7 @@ namespace ArmourMod | ||
12 | 12 | { |
13 | 13 | public class EntityArmourPlayer : EntityPlayer |
14 | 14 | { |
15 | + private static string _clientHookIdKey = @"ClientDelayHookId"; | |
15 | 16 | protected ICoreAPI CoreAPI; |
16 | 17 | protected ICoreClientAPI ClientAPI; |
17 | 18 | protected ICoreServerAPI ServerAPI; |
@@ -23,24 +24,46 @@ namespace ArmourMod | ||
23 | 24 | //Pre-compute values; |
24 | 25 | private DamageFilter finalFilter; |
25 | 26 | |
26 | - private long recurringClientDelayHookId; | |
27 | - private long oneShotDelayId; | |
28 | 27 | private bool slotEventAttached; |
29 | 28 | |
30 | 29 | |
31 | 30 | internal ArmourModConfig CachedConfiguration |
32 | 31 | { |
33 | 32 | get |
34 | - { | |
33 | + { | |
35 | 34 | if (CoreAPI.Side.IsServer( )) { |
36 | 35 | return ( ArmourModConfig )ServerAPI.ObjectCache[ArmourModHookin._configFilename]; |
37 | 36 | } else { |
38 | 37 | return ( ArmourModConfig )ClientAPI.ObjectCache[ArmourModHookin._configFilename]; |
39 | 38 | } |
40 | - | |
41 | 39 | } |
42 | 40 | } |
43 | 41 | |
42 | + private long CachedClientCallbackId | |
43 | + { | |
44 | + get | |
45 | + { | |
46 | + if (ClientAPI.ObjectCache.ContainsKey(_clientHookIdKey + ClientAPI.World.Player.PlayerUID)) | |
47 | + { | |
48 | + return (long)ClientAPI.ObjectCache[_clientHookIdKey + ClientAPI.World.Player.PlayerUID]; | |
49 | + } else { | |
50 | + return -1L; | |
51 | + } | |
52 | + } | |
53 | + set | |
54 | + { | |
55 | + if (ClientAPI.ObjectCache.ContainsKey(_clientHookIdKey + ClientAPI.World.Player.PlayerUID)) | |
56 | + { | |
57 | + Logger.Error("Trying to register duplicate callback-id [value: {0}]", value); ; | |
58 | + } | |
59 | + else | |
60 | + { | |
61 | + ClientAPI.ObjectCache[_clientHookIdKey + ClientAPI.World.Player.PlayerUID] = value; | |
62 | + } | |
63 | + } | |
64 | + } | |
65 | + | |
66 | + | |
44 | 67 | public Dictionary<EnumCharacterDressType,Item> RenderableWornArmours { get; private set;}//Needs to be client side |
45 | 68 | |
46 | 69 | public override void Initialize(Vintagestory.API.Common.Entities.EntityProperties properties, ICoreAPI api, long chunkindex3d) |
@@ -65,24 +88,26 @@ namespace ArmourMod | ||
65 | 88 | } |
66 | 89 | } |
67 | 90 | |
68 | - public override void OnEntityLoaded() | |
91 | + public override void OnGameTick(float dt) | |
69 | 92 | { |
70 | - base.OnEntityLoaded(); | |
71 | - #if DEBUG | |
72 | - Logger.VerboseDebug( "OnEntityLoaded - EntityArmourPlayer" ); | |
93 | + base.OnGameTick(dt); | |
73 | 94 | |
74 | - Logger.VerboseDebug( "Side:{0}, gearInv == null?{1}", CoreAPI.Side.ToString( ), this.GearInventory == null ); | |
75 | - #endif | |
76 | 95 | |
77 | - if ( CoreAPI.Side.IsClient() ) { | |
96 | + if (CoreAPI.Side.IsClient( )) { | |
78 | 97 | |
79 | - //Attach to Inventory events | |
80 | - #if DEBUG | |
81 | - Logger.VerboseDebug( "Side:{0}, gearInv == null?{1}", CoreAPI.Side.ToString( ), this.GearInventory == null ); | |
82 | - #endif | |
98 | + if (ClientAPI.World.Player != null) { | |
83 | 99 | |
84 | - | |
85 | - this.oneShotDelayId = ClientAPI.Event.RegisterGameTickListener(ClientDelayHook, 250); | |
100 | + if (this.CachedClientCallbackId > 0) { | |
101 | + #if DEBUG | |
102 | + Logger.VerboseDebug("[OnEntityLoaded] Duplicate event attach prevented"); | |
103 | + #endif | |
104 | + } else { | |
105 | + this.CachedClientCallbackId = ClientAPI.Event.RegisterGameTickListener(ClientDelayHook, 250); | |
106 | + #if DEBUG | |
107 | + Logger.VerboseDebug("[OnEntityLoaded] oneShotDelayId: {0}", this.CachedClientCallbackId); | |
108 | + #endif | |
109 | + } | |
110 | + } | |
86 | 111 | } |
87 | 112 | } |
88 | 113 |
@@ -258,43 +283,29 @@ namespace ArmourMod | ||
258 | 283 | |
259 | 284 | protected void ClientDelayHook(float delay) |
260 | 285 | { |
261 | - ClientAPI.Event.UnregisterGameTickListener(oneShotDelayId); | |
286 | + #if DEBUG | |
287 | + Logger.VerboseDebug("[clientDelayHook] oneShotDelayId: {0}", this.CachedClientCallbackId); | |
288 | + #endif | |
262 | 289 | |
263 | 290 | if (this.GearInventory == null) { |
264 | 291 | Logger.Error("ClientDelayHook: base.GearInventory IS NULL! "); |
265 | - recurringClientDelayHookId = ClientAPI.Event.RegisterCallback(RecurringClientDelayHook, 100); | |
292 | + | |
266 | 293 | return; |
267 | 294 | } |
268 | 295 | |
269 | 296 | if (slotEventAttached == false) { |
270 | 297 | slotEventAttached = true; |
298 | + #if DEBUG | |
299 | + Logger.VerboseDebug("Attached ClientWatchSlotModified (ClientDelayHook)"); | |
300 | + #endif | |
271 | 301 | this.GearInventory.SlotModified += ClientWatchSlotModified; |
272 | 302 | } |
273 | 303 | |
274 | - PopulateWornArmourModels( ); | |
275 | - } | |
276 | - | |
277 | - protected void RecurringClientDelayHook(float delayed) | |
278 | - { | |
279 | - if (this.GearInventory == null) { | |
280 | - Logger.Error("RecurringClientDelayHook: base.GearInventory IS NULL! "); | |
304 | + ClientAPI.Event.UnregisterGameTickListener(this.CachedClientCallbackId); | |
281 | 305 | |
282 | - return; | |
283 | - } else { | |
284 | - Logger.Notification("RecurringClientDelayHook: Finally the Gear data arrived - can proceed with event hooks"); | |
285 | - | |
286 | - ClientAPI.Event.UnregisterCallback(recurringClientDelayHookId); | |
287 | - | |
288 | - if (slotEventAttached == false) { | |
289 | - slotEventAttached = true; | |
290 | - this.GearInventory.SlotModified += ClientWatchSlotModified; | |
291 | - } | |
292 | - PopulateWornArmourModels( ); | |
293 | - } | |
306 | + PopulateWornArmourModels( ); | |
294 | 307 | } |
295 | 308 | |
296 | - | |
297 | - | |
298 | 309 | private void ServerWatchSlotModified (int slotId) |
299 | 310 | { |
300 | 311 | var watchedSlot = this.GearInventory[slotId]; |
@@ -332,8 +343,9 @@ namespace ArmourMod | ||
332 | 343 | private void ClientWatchSlotModified (int slotId) |
333 | 344 | { |
334 | 345 | #if DEBUG |
335 | - Logger.VerboseDebug( "(Client) WatchSlotModified:{0}", slotId ); | |
346 | + Logger.VerboseDebug( "(Client) WatchSlotModified:{0} PlayerID: {1} InventoryID: {2}", slotId, ClientAPI.World.Player.PlayerUID,this.GearInventory.InventoryID ); | |
336 | 347 | #endif |
348 | + | |
337 | 349 | var watchedSlot = this.GearInventory[slotId]; |
338 | 350 | |
339 | 351 | if ( !watchedSlot.Empty ) { |
@@ -468,9 +480,9 @@ namespace ArmourMod | ||
468 | 480 | |
469 | 481 | if ( CheckIfClothesIsArmour(itemSlot) ) |
470 | 482 | { |
471 | -#if DEBUG | |
483 | + #if DEBUG | |
472 | 484 | Logger.VerboseDebug( "Now wearing armour:{0}", itemSlot.Itemstack.Item.Code.ToString( ) ); |
473 | -#endif | |
485 | + #endif | |
474 | 486 | |
475 | 487 | if (RenderableWornArmours.ContainsKey(( EnumCharacterDressType )slotId)) { |
476 | 488 | Logger.Warning("DUPLICATE assignment; Armour in slot: {0} named: {1}", slotId, itemSlot.Itemstack.Item.Code.ToString( )); |
@@ -0,0 +1,51 @@ | ||
1 | +using System; | |
2 | +using System.Collections.Generic; | |
3 | +using System.Linq; | |
4 | +using System.Text; | |
5 | +using System.Threading.Tasks; | |
6 | + | |
7 | +using Vintagestory.API.Common; | |
8 | +using Vintagestory.API.Common.Entities; | |
9 | +using Vintagestory.API.Config; | |
10 | +using Vintagestory.GameContent; | |
11 | + | |
12 | +namespace ArmourMod | |
13 | +{ | |
14 | + public class ItemArmour : ItemDress | |
15 | + { | |
16 | + public override void GetHeldItemInfo(ItemStack stack, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo) | |
17 | + { | |
18 | + //base.GetHeldItemInfo(stack, dsc, world, withDebugInfo); | |
19 | + | |
20 | + if (this.Durability > 1) { | |
21 | + dsc.AppendLine(Lang.Get("Durability: {0} / {1}", new object[] { | |
22 | + stack.Attributes.GetInt ("durability", this.Durability), | |
23 | + this.Durability})); | |
24 | + } | |
25 | + | |
26 | + //Display Protection values | |
27 | + var blunt = stack.ItemAttributes["BluntProtection"].AsFloat( ); | |
28 | + var piercing = stack.ItemAttributes["PiercingProtection"].AsFloat( ); | |
29 | + var slashing = stack.ItemAttributes["SlashingProtection"].AsFloat( ); | |
30 | + var crushing = stack.ItemAttributes["CrushingProtection"].AsFloat( ); | |
31 | + var flame = stack.ItemAttributes["FireProtection"].AsFloat( ); | |
32 | + | |
33 | + dsc.AppendFormat("Protection:\n Blunt {0:P1}\n Piercing {1:P1}\n Slashing {2:P1}\n Crushing {3:P1}\n Flame {4:P1}", | |
34 | + blunt, | |
35 | + piercing, | |
36 | + slashing, | |
37 | + crushing, | |
38 | + flame); | |
39 | + | |
40 | + EnumCharacterDressType dresstype; | |
41 | + string strdress = stack.ItemAttributes["clothescategory"].AsString( ); | |
42 | + | |
43 | + if (!Enum.TryParse(strdress, true, out dresstype)) { | |
44 | + dsc.AppendLine(Lang.Get("Cloth Category: Unknown")); | |
45 | + } else { | |
46 | + dsc.AppendLine(Lang.Get("Cloth Category: {0}", Lang.Get("clothcategory-" + stack.ItemAttributes["clothescategory"].AsString( )))); | |
47 | + } | |
48 | + } | |
49 | + } | |
50 | +} | |
51 | + |
@@ -73,6 +73,7 @@ | ||
73 | 73 | <Compile Include="Armour\AmourMeshRenderer.cs" /> |
74 | 74 | <Compile Include="Armour\ArmourModelData.cs" /> |
75 | 75 | <Compile Include="Armour\ArmourModConfig.cs" /> |
76 | + <Compile Include="Armour\ItemArmour.cs" /> | |
76 | 77 | </ItemGroup> |
77 | 78 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
78 | 79 | <ItemGroup> |
@@ -1,6 +1,6 @@ | ||
1 | 1 | { |
2 | 2 | code: "clothes", |
3 | - class: "ItemDress", | |
3 | + class: "ItemArmour", | |
4 | 4 | variantgroups: [ |
5 | 5 | { code: "category", states: ["head"] }, |
6 | 6 | { code: "head", combine: "SelectiveMultiply", onVariant: "category", |
@@ -1,6 +1,6 @@ | ||
1 | 1 | { |
2 | 2 | code: "clothes", |
3 | - class: "ItemDress", | |
3 | + class: "ItemArmour", | |
4 | 4 | variantgroups: [ |
5 | 5 | { code: "category", states: ["upperbodyover"] }, |
6 | 6 | { code: "upperbodyover", combine: "SelectiveMultiply", onVariant: "category", |