static void Main(string[] args) { NetworkManager nm = new NetworkManager(); obs = new DataObserver(); vwc = new VWClient(new DataFactory(nm), nm); nm.Subscribe(vwc); nm.Subscribe(obs); nm.Subscribe(new LoggedObserver()); Logger.SetPath(".\\log.txt"); Logger.Log("Scooby Dooby Dooo!"); //vwc.RequestRecords(PrintDataRecords, 0, 50); //vwc.RequestRecords(null,0, 1000); vwc.RequestRecords(DummyMethod, 0, 10); Thread t = new Thread(() => tFunct(recs)); vwc.RequestRecords(DummyMethod, 0, 9); Console.WriteLine("DONE"); Console.ReadKey(); Logger.Close(); }
private void ReAssignWorkers(bool manipulatedChanged = false, bool rawChanged = false) { if (this.UnitObserver != null) { this.UnitObserver.Dispose(); this.UnitObserver = null; } this.UnitObserver = new DataObserver <IAbilityUnit>(unit => this.workers[unit.UnitHandle] = this.RawDamageWorkerAssign(unit)); if (!rawChanged && manipulatedChanged) { foreach (var skillRawDamageCalculatorWorker in this.workers) { skillRawDamageCalculatorWorker.Value.ManipulatedDamageWorker = this.DamageWorkerAssign(skillRawDamageCalculatorWorker.Value.Target); } } foreach (var teamOtherTeam in this.Skill.Owner.Team.OtherTeams) { if (rawChanged) { foreach (var unitManagerUnit in teamOtherTeam.UnitManager.Units) { this.UnitObserver.OnNext(unitManagerUnit.Value); } } this.UnitObserver.Subscribe(teamOtherTeam.UnitManager.UnitAdded); } }
public void Initialize() { this.ApplyEffect(); Console.WriteLine("applying effect " + this.Skill.Name); this.levelObserver = new DataObserver <ISkillLevel>(level => this.UpdateEffect()); this.levelObserver.Subscribe(this.Skill.Level); }
public virtual void Initialize() { this.ApplyEffect(); this.levelObserver = new DataObserver <ISkillLevel>(level => this.UpdateEffect()); this.levelObserver.Subscribe(this.Modifier.SourceSkill.Level); }
public ManaBar(IAbilityUnit unit, Vector2 size) { this.Unit = unit; this.manaObserver = new DataObserver <IMana>(this.OnNext); this.Unit.Mana.Subscribe(this.manaObserver); this.Size = size; }
public virtual void Initialize() { this.castPointUpdate = new LevelUpdater <IAbilitySkill, double>( this.Skill, () => this.Skill.SourceAbility.FindCastPoint()); this.speedUpdate = new LevelUpdater <IAbilitySkill, float>( this.Skill, () => this.Skill.SourceAbility.GetProjectileSpeed()); this.castRangeUpdate = new LevelUpdater <IAbilitySkill, float>( this.Skill, () => this.Skill.SourceAbility.GetCastRange()); this.manaObserver = new DataObserver <IMana>( mana => { this.EnoughMana = mana.Current >= this.Skill.SourceAbility.ManaCost; }); this.manaObserver.Subscribe(this.Skill.Owner.Mana); if (this.Skill.Cooldown != null) { this.cooldownObserver = new DataObserver <ICooldown>( cooldown => { this.Cooldown = cooldown.Current; this.IsOnCooldown = this.Cooldown > 0; }); this.cooldownObserver.Subscribe(this.Skill.Cooldown); } }
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary> public override void Dispose() { base.Dispose(); this.levelObserver.Dispose(); this.levelObserver = null; this.enableObserver.Dispose(); this.enableObserver = null; this.healthbarPosObserver.Dispose(); this.healthbarPosObserver = null; }
public StatusPanel(IAbilityUnit unit, Vector2 size) : base(unit) { this.Unit = unit; this.unitName = new DrawText { Color = Color.PapayaWhip, Text = Game.Localize(unit.Name) + " -", TextSize = new Vector2((float)(size.Y / 2)), Shadow = true }; this.level = new DrawText() { Color = Color.PapayaWhip, Text = unit.SourceUnit.Level.ToString(), TextSize = new Vector2((float)(size.Y / 2)), Shadow = true }; this.levelNumber = new Number(NumberTextureColor.Default, true, (float)size.Y) { Value = 0 }; this.Background = new DrawRect(this.BackgroundColor) { Size = size }; this.levelObserver = new DataObserver <IUnitLevel>( unitLevel => { // this.level.Text = unitLevel.Current.ToString(); this.levelNumber.Value = (int)unitLevel.Current; this.Panel?.UpdateSize(); }); this.levelObserver.Subscribe(this.Unit.Level); this.circleIcon = new DrawRect(this.Unit.IconDrawer.MinimapIcon) { Size = new Vector2((float)(size.Y * 1.5)) }; this.setSize = size; this.enableObserver = new DataObserver <bool>(this.EnabledAction()); this.healthbarPosObserver = new DataObserver <StringList>( list => { if (list.SelectedIndex == 0) { this.ChangePosition(PanelDirection.Left); } else { this.ChangePosition(PanelDirection.Right); } this.Panel?.UpdateSize(); }); // this.Size = size; }
public HealthBar(IAbilityUnit unit, Vector2 size) { this.Unit = unit; this.healthObserver = new DataObserver <IHealth>(this.UpdateHealth); this.maxHealthObserver = this.UpdateSeparators; this.healthObserver.Subscribe(this.Unit.Health); this.Size = size; this.lastSeparatedValue = 0; this.UpdateSeparators(); this.Unit.Health.MaximumHealthChange.Subscribe(this.maxHealthObserver); }
/// <summary>Initializes a new instance of the <see cref="SkillRawDamageCalculatorWorker" /> class.</summary> /// <param name="skill">The skill.</param> /// <param name="target">The target.</param> /// <param name="manipulatedDamageWorker">The manipulated damage worker.</param> protected SkillRawDamageCalculatorWorker( IAbilitySkill skill, IAbilityUnit target, ISkillManipulatedDamageCalculatorWorker manipulatedDamageWorker) { this.Skill = skill; this.Target = target; this.ManipulatedDamageWorker = manipulatedDamageWorker; this.levelObserver = new DataObserver <ISkillLevel>(level => { this.UpdateRawDamage(); }); this.levelObserver.Subscribe(this.Skill.Level); }
public virtual void Initialize() { this.modifierAddObserver = new DataObserver <Modifier>(modifier => this.ModifierAdded(modifier)); this.modifierAddObserver.Subscribe(this.Unit.Modifiers.ModifierAdded); this.modifierRemoveObserver = new DataObserver <Modifier>(modifier => this.ModifierRemoved(modifier)); this.modifierRemoveObserver.Subscribe(this.Unit.Modifiers.ModifierRemoved); foreach (var sourceUnitModifier in this.Unit.SourceUnit.Modifiers) { this.ModifierAdded(sourceUnitModifier); } }
public SkillOverlay(IAbilitySkill skill) { this.Skill = skill; this.icon = new DrawRect(skill.Texture); this.blueOverlay = new DrawRect(new Color(20, 20, 100, 220)); this.blackOverlay = new DrawRect(new Color(40, 40, 40, 180)); this.CooldownText = new DrawText { Text = string.Empty, Color = Color.FloralWhite, FontFlags = FontFlags.None, Shadow = true }; this.manaText = new DrawText { Text = string.Empty, Color = new Color(180, 200, 255), FontFlags = FontFlags.None, Shadow = true }; this.BorderColor = this.NotLearnedColor; this.cooldownNumber = new Number( NumberTextureColor.Default, true, this.Skill.Owner.ScreenInfo.HealthBarSize.Y / 2); this.manaNumber = new Number(NumberTextureColor.Blue, true); this.Skill.DisposeNotifier.Subscribe(this.Dispose); if (this.Skill.Cooldown == null) { return; } this.manaObserver = new DataObserver <IMana>(this.OnNext); this.manaObserver.Subscribe(this.Skill.Owner.Mana); this.OnNext(this.Skill.Owner.Mana); this.coolDownObserver = new DataObserver <ICooldown>(this.OnNext); this.coolDownObserver.Subscribe(this.Skill.Cooldown); this.offCooldownObserver = new DataObserver <ICooldown>( cooldown => { if (!this.Skill.CastData.EnoughMana) { this.BorderColor = this.NotEnoughManaColor; return; } this.BorderColor = this.ReadyColor; }); this.offCooldownObserver.Subscribe(this.Skill.Cooldown.OffCooldownProvider); }
public virtual void Initialize() { this.keyBindObserver = new DataObserver <KeyBind>( bind => { if (bind.Active) { this.Activate(); } else { this.Deactivate(); } }); }
public void ShouldSubscribeBondPrices() { ManualResetEvent readyEvent = new ManualResetEvent(false); var identifier = "T 0.375 04/30/2016"; ConcurrentDictionary<string, RealTimeBondData> bondPriceCache = new ConcurrentDictionary<string, RealTimeBondData>(); var dataObserver = new DataObserver(bondPriceCache, new Dictionary<string, int>(), new HashSet<Future>()); var options = new Options {IdentifierType = "RIC", Source = null, Fields = new[] {"PRIMACT_1", "SEC_ACT_1"}}; CarbonSubscriber.GetInstance() .GetCarbonClientInstance() .SubscribeToMarketData(identifier, dataObserver, options: options); readyEvent.WaitOne(TimeSpan.FromSeconds(100)); }
public BondSpreadCalculator(BondSpreadServiceModel bondSpreadServiceModel, CurveBuilder curveBuilder, FutureBuilder futureBuilder, FutureEnrichment futureEnricher, ForwardBuilder forwardBuilder, InterestCurves curves) { this.bondSpreadServiceModel = bondSpreadServiceModel; this.curveBuilder = curveBuilder; this.futureBuilder = futureBuilder; this.futureEnricher = futureEnricher; this.forwardBuilder = forwardBuilder; this.curves = curves; carbonFieldMap = CarbonModel.GetEnumToFieldMapping(new[] { "bid", "ask", "primAct1", "secAct1" }); dataObserver = new DataObserver(bondPriceCache, carbonFieldMap, FutureCache); dataObserver.Subscribe(dataObserveSubject); }
protected PanelBase(IAbilityUnit unit) { this.Unit = unit; this.sizeIncreaseObserver = new DataObserver <Slider>( slider => { this.SizeIncrease = (float)(slider.Value * (1080 / HUDInfo.ScreenSizeY()) / 20); }); this.enableObserver = new DataObserver <bool>(this.EnabledAction()); this.positionObserver = new DataObserver <StringList>( list => { this.HealthBarPositionAction().Invoke(list); this.ChangePosition((PanelDirection)list.SelectedIndex); this.Panel?.UpdateSize(); }); }
/// <summary>The compose.</summary> /// <param name="skill">The skill.</param> public override void Compose(IAbilitySkill skill) { base.Compose(skill); var skillAddedObserver = new DataObserver <IAbilitySkill>( add => { if (add.IsItem && add.SourceItem.Id == AbilityId.item_ultimate_scepter) { skill.AddPart <IModifierGenerator>( abilitySkill => new ModifierGenerator(skill) { Workers = new List <ModifierGeneratorWorker> { new ModifierGeneratorWorker( "modifier_centaur_stampede", modifier => modifier.AssignModifierEffectApplier( new ModifierEffectApplier(modifier) { Workers = new List <IEffectApplierWorker> { new DamageReductionEffectApplierWorker ( modifier, false, abilityModifier => 0.6) } }), false, true, true) } }); } }); skillAddedObserver.Subscribe(skill.Owner.SkillBook.SkillAdded); skill.DisposeNotifier.Subscribe(() => skillAddedObserver.Dispose()); }
public virtual void Initialize() { this.IsDisposed = false; this.HealthBar = new HealthBar(this.Unit, this.Unit.ScreenInfo.HealthBarSize) { Color = this.Unit.IsEnemy ? new Color(230, 70, 70) : new Color(90, 200, 70), BackgroundColor = Color.Black }; this.LeftPanel = new LeftPanelField(this.Unit, this.HealthBar); this.Panels.Add(this.LeftPanel); this.LeftPanel.SizeChanged.Subscribe(this.UpdateSizeAndPosition); this.TopPanel = new TopPanelField(this.Unit, this.HealthBar); this.Panels.Add(this.TopPanel); this.TopPanel.SizeChanged.Subscribe(this.UpdateSizeAndPosition); this.RightPanel = new RightPanelField(this.Unit, this.HealthBar); this.Panels.Add(this.RightPanel); this.RightPanel.SizeChanged.Subscribe(this.UpdateSizeAndPosition); // this.Elements.Add(this.HealthBar); this.ManaBar = new ManaBar( this.Unit, new Vector2(this.HealthBar.Size.X, (float)(this.HealthBar.Size.Y / 2))) { Color = new Color(70, 90, 200), BackgroundColor = Color.Black }; this.BotPanel = new BotPanelField(this.Unit); this.Panels.Add(this.BotPanel); this.BotPanel.SizeChanged.Subscribe(this.UpdateSizeAndPosition); ///this.Elements.Add(this.ManaBar); this.TopPanel.AddElement(new StatusPanel(this.Unit, new Vector2((float)(this.HealthBar.Size.Y * 1.2)))); // this.Unit.Position.Subscribe(this); this.screenInfoObserver = new DataObserver <IScreenInfo>(info => { this.Update(); }); this.screenInfoObserver.Subscribe(this.Unit.ScreenInfo.UpdateProvider); this.Unit.DataReceiver.Drawings.Add(this.OnDraw); // this.circleIcon = new DrawRect(Textures.GetHeroRoundTexture(this.Unit.Name)) // { Size = new Vector2((float)(this.HealthBar.Size.Y * 2.5)) }; }
protected override void RealTestOutPut() { var tracker = new DataTracker(); var tracker1 = new DataObserver("tracker1"); var tracker2 = new DataObserver("tracker2"); tracker1.Subscribe(tracker); tracker2.Subscribe(tracker); tracker.Track(new DataSource() { a = 888 }); tracker1.UnSubscribe(); tracker.Track(new DataSource() { a = 233 }); tracker.Track(null); }
public SpellOverlay(IAbilitySkill skill) : base(skill) { // this.levelText = new DrawText // { Color = Color.White, Shadow = true, Text = this.Skill.Level.Current.ToString() }; this.levelNumber = new Number(NumberTextureColor.Default, true) { Value = (int)this.Skill.Level.Current }; this.levelObserver = new DataObserver <ISkillLevel>( level => { // this.levelText.Text = level.Current.ToString(); this.levelNumber.Value = (int)level.Current; this.OnSizeSet(); this.OnPositionSet(); }); this.levelObserver.Subscribe(this.Skill.Level); this.levelTextBackground = new DrawRect(new Color(0, 0, 0, 210)); DelayAction.Add(100, this.OnPositionSet); }
static void Main(string[] args) { DataGenerator dataGenerator = new DataGenerator(); DataObserver dataObserver1 = new DataObserver("O1"); dataGenerator.Subscribe(dataObserver1); DataObserver dataObserver2 = new DataObserver("O2"); dataGenerator.Subscribe(dataObserver2); DataObserver dataObserver3 = new DataObserver("O3"); dataGenerator.Subscribe(dataObserver3); DataObserver dataObserver4 = new DataObserver("O4"); dataGenerator.Subscribe(dataObserver4); DataObserver dataObserver5 = new DataObserver("O5"); dataGenerator.Subscribe(dataObserver5); dataGenerator.Run(); Console.ReadLine(); }
public WorldIcon(IAbilityUnit unit) { this.Unit = unit; this.screenInfoObserver = new DataObserver <IScreenInfo>(info => this.UpdatePosition()); }
internal WorldIcon(IAbilityUnit unit) { this.Unit = unit; this.screenInfoObserver = new DataObserver <IScreenInfo>(info => this.UpdatePosition()); this.drawWorldIcon = new ActionExecutor(this.Draw); }
public override void Initialize() { base.Initialize(); this.BotPanel.AddElement( new ItemPanel( this.Unit, PanelDirection.Bottom, new Vector2(this.HealthBar.Size.Y * 3, (float)(this.HealthBar.Size.Y * 2.2)))); this.skillbook = this.Unit.SkillBook as InvokerSkillBook; this.InvokerSkillPanel = new InvokerSkillPanel( this.Unit, PanelDirection.Bottom, new Vector2(this.HealthBar.Size.Y * 3), skill => !skill.IsItem && skill.Name != "invoker_empty1" && skill.Name != "invoker_empty2" && !(skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_1 || skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_2 || skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_3 || skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_6) && (!skill.SourceAbility.IsHidden || skill.SkillHandle.Equals(this.skillbook?.InvokableSkill?.SkillHandle))); // { // OrderFunction = // skill => // skill.SourceAbility.IsHidden ? 0 : 10 + (uint)skill.SourceAbility.AbilitySlot // }; // this.spellPanel1.PositionFromHealthBarFunc = () => new Vector2(-this.spellPanel1.Size.X, 0); this.LeftPanel.AddElement(this.InvokerSkillPanel); this.spellPanel2 = new SkillPanel( this.Unit, PanelDirection.Bottom, new Vector2(this.HealthBar.Size.Y * 2), skill => !skill.IsItem && !(skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_1 || skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_2 || skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_3 || skill.SourceAbility.AbilitySlot == AbilitySlot.Slot_6) && skill.Name != "invoker_empty1" && skill.Name != "invoker_empty2" && skill.SourceAbility.IsHidden && !skill.Equals(this.skillbook.InvokableSkill), o => o.Skill.Json.CastPriority); // this.spellPanel2.PositionFromHealthBarLeftFunc = // () => new Vector2(-this.spellPanel1.Size.X - this.spellPanel2.Size.X, 0); this.LeftPanel.AddElement(this.spellPanel2); this.skillAddObserver = new DataObserver <SkillAdd>(this.OnNext); this.modifiers = this.Unit.Modifiers as InvokerModifiers; this.invokableSkillChangeAction = () => { this.InvokerSkillPanel.UpdateSkills(); this.spellPanel2.UpdateSkills(); }; this.skillbook.InvokableSkillChange.Subscribe(this.invokableSkillChangeAction); this.becomeVisibleAction = () => { this.InvokerSkillPanel.UpdateSkills(); this.spellPanel2.UpdateSkills(); }; this.Unit.Visibility.BecomeVisibleNotifier.Subscribe(this.becomeVisibleAction); }
internal AbilityManager() { // AbilityBootstrapper.ComposeParts(this); this.abilitySkillPartObserver = new DataObserver <IAbilitySkillPart>(this.AbilitySkillPartAdded); }
public virtual void Initialize() { this.castPointUpdate = new LevelUpdater <IAbilitySkill, double>( this.Skill, () => Math.Max(this.Skill.SourceAbility.FindCastPoint(), 0.1)); this.speedUpdate = new LevelUpdater <IAbilitySkill, float>( this.Skill, () => this.Skill.SourceAbility.GetProjectileSpeed()); var manaSub = false; if (this.Skill.SourceAbility.ManaCost > 0) { manaSub = true; this.manaObserver = new DataObserver <IMana>( mana => { if (this.Skill.SourceAbility.IsValid) { this.EnoughMana = mana.Current > this.Skill.SourceAbility.ManaCost; } else { Console.WriteLine( "SkillCastData: receiving mana data for invalid skill " + this.Skill.Name); } }); this.manaObserver.Subscribe(this.Skill.Owner.Mana); } else { DataObserver <ISkillLevel> levelObserver = null; levelObserver = new DataObserver <ISkillLevel>( level => { if (manaSub) { return; } if (this.Skill.SourceAbility.ManaCost > 0) { manaSub = true; this.manaObserver = new DataObserver <IMana>( mana => { if (this.Skill.SourceAbility.IsValid) { this.EnoughMana = mana.Current > this.Skill.SourceAbility.ManaCost; } else { Console.WriteLine( "SkillCastData: receiving mana data for invalid skill " + this.Skill.Name); } }); this.manaObserver.Subscribe(this.Skill.Owner.Mana); } }); levelObserver.Subscribe(this.Skill.Level); } if (this.Skill.Cooldown != null) { this.cooldownObserver = new DataObserver <ICooldown>( cooldown => { this.Cooldown = cooldown.Current; this.IsOnCooldown = this.Cooldown > 0; }); this.cooldownObserver.Subscribe(this.Skill.Cooldown); } }
public virtual void Initialize() { if (this.Skill.AbilityInfo.DamageString != null) { if (this.Skill.AbilityInfo.DamageScepterString != null) { if (this.Skill.Owner.SourceUnit.HasModifier("modifier_item_ultimate_scepter_consumed")) { this.RawDamageWorkerAssign = unit => new StringDataAghaDamageCalculatorWorker( this.Skill, unit, this.DamageWorkerAssign(unit)); } else if (this.Skill.Owner.SourceUnit.HasModifier("modifier_item_ultimate_scepter")) { this.RawDamageWorkerAssign = unit => new StringDataAghaDamageCalculatorWorker( this.Skill, unit, this.DamageWorkerAssign(unit)); var observer = new DataObserver <IAbilitySkill>(); observer.OnNextAction = remove => { if (remove.IsItem && remove.SourceItem.Id == AbilityId.item_ultimate_scepter) { this.RawDamageWorkerAssign = unit => new StringDataDamageCalculatorWorker( this.Skill, unit, this.DamageWorkerAssign(unit)); observer.Dispose(); } }; observer.Subscribe(this.Skill.Owner.SkillBook.SkillRemoved); this.Skill.DisposeNotifier.Subscribe(() => observer.Dispose()); } } else { this.RawDamageWorkerAssign = unit => new StringDataDamageCalculatorWorker(this.Skill, unit, this.DamageWorkerAssign(unit)); } } else { this.RawDamageWorkerAssign = unit => new GetDamageCalculatorWorker(this.Skill, unit, this.DamageWorkerAssign(unit)); } if (this.DamageType == DamageType.Magical) { this.DamageWorkerAssign = unit => new MagicalSkillDamageCalculatorWorker(this.Skill, unit); } else if (this.DamageType == DamageType.Physical) { this.DamageWorkerAssign = unit => new PhysicalSkillDamageCalculatorWorker(this.Skill, unit); } else if (this.DamageType == DamageType.Pure) { this.DamageWorkerAssign = unit => new PureSkillDamageCalculatorWorker(this.Skill, unit); } else { this.DamageWorkerAssign = unit => new HealthRemovalSkillDamageCalculatorWorker(this.Skill, unit); } }
public SkillPanel( IAbilityUnit unit, PanelDirection direction, Vector2 defaultObjectSize, Func <IAbilitySkill, bool> selectionCondition, Func <SkillPanelObject, uint> orderFunction = null, Func <SkillPanelObject, Vector2, Vector2> objectSizeFunction = null) : base(unit, direction, defaultObjectSize, orderFunction, objectSizeFunction ?? ((o, vector2) => { if (o.Skill.Level.Current <= 0) { return(vector2 * new Vector2(0.5f)); } else if (o.Skill.Cooldown == null && o.Skill.Charges == null) { return(vector2 * new Vector2(0.65f)); } return(vector2); })) { this.Unit = unit; this.levelObserver = new DataObserver <ISkillLevel>(level => { this.ObjectManager.UpdateSize(); }); this.SelectionCondition = selectionCondition; // Console.WriteLine(this.tempDictionary.Count); // foreach (var keyValuePair in this.Unit.SkillBook.AllSkills) // { // if (this.SelectionCondition.Invoke(keyValuePair.Value)) // { // var o = new SkillPanelObject(keyValuePair.Value); // Console.WriteLine(keyValuePair.Value.Name); // this.tempDictionary.Add(keyValuePair.Key, o); // this.AddObject(o); // this.levelObserver.Subscribe(keyValuePair.Value.Level); // } // } this.skillAddObserver = new DataObserver <SkillAdd>( add => { if (this.SelectionCondition.Invoke(add.Skill)) { var o = new SkillPanelObject(add.Skill); this.tempDictionary.Add(add.Skill.SkillHandle, o); this.AddObject(o); } this.levelObserver.Subscribe(add.Skill.Level); }); this.skillAddObserver.Subscribe(this.Unit.SkillBook.SkillAdd); this.skillRemoveObserver = new DataObserver <SkillRemove>( remove => { if (!this.SelectionCondition.Invoke(remove.Skill)) { return; } this.RemoveObject(this.TempDictionary[remove.Skill.SkillHandle]); }); this.skillRemoveObserver.Subscribe(unit.SkillBook.SkillRemove); }