private void ProcessDamage(IGraphNode targetNode, ITacticalAct tacticalAct, IActor actor, ActorViewModel actorViewModel) { var targetActorViewModel = ActorViewModels.SingleOrDefault(x => x.Actor.Node == targetNode); var targetStaticObjectViewModel = _staticObjectViewModels.SingleOrDefault(x => x.StaticObject.Node == targetNode); var canBeHitViewModel = (ICanBeHitSectorObject)targetActorViewModel ?? targetStaticObjectViewModel; if (canBeHitViewModel is null) { return; } actorViewModel.GraphicRoot.ProcessHit(canBeHitViewModel.Position); var sfxObj = _container.InstantiatePrefab(HitSfx, transform); var sfx = sfxObj.GetComponent <HitSfx>(); canBeHitViewModel.AddHitEffect(sfx); // Проверяем, стрелковое оружие или удар ближнего боя if (tacticalAct.Stats.Range?.Max > 1) { sfx.EffectSpriteRenderer.sprite = sfx.ShootSprite; // Создаём снаряд CreateBullet(actor, targetNode); } }
private async void ActorOnUsedAct(object sender, UsedActEventArgs e) { await Task.Factory.StartNew(() => { var actor = GetActorFromEventSender(sender); var actorHexNode = actor.Node as HexNode; var targetHexNode = e.TargetNode as HexNode; // Визуализируем удар. var actorViewModel = ActorViewModels.Single(x => x.Actor == actor); var actEffect = e.TacticalAct.Stats.Effect; switch (actEffect) { case TacticalActEffectType.Damage: ProcessDamage(e.TargetNode, e.TacticalAct, actor, actorViewModel); break; case TacticalActEffectType.Heal: ProcessHeal(actorViewModel); break; case TacticalActEffectType.Undefined: default: throw new InvalidOperationException($"Неизвестный тип воздействия {actEffect}."); } }, CancellationToken.None, TaskCreationOptions.None, _taskScheduler); }
private void CreateBullet(IActor actor, IGraphNode targetNode) { var actorViewModel = ActorViewModels.Single(x => x.Actor == actor); var targetActorViewModel = ActorViewModels.SingleOrDefault(x => x.Actor.Node == targetNode); var targetStaticObjectViewModel = _staticObjectViewModels.SingleOrDefault(x => x.StaticObject.Node == targetNode); var canBeHitViewModel = (ICanBeHitSectorObject)targetActorViewModel ?? targetStaticObjectViewModel; var bulletTracer = Instantiate(GunShootTracer, transform); bulletTracer.FromPosition = actorViewModel.transform.position; bulletTracer.TargetPosition = canBeHitViewModel.Position; }
private async void Monster_Dead(object sender, EventArgs e) { await Task.Factory.StartNew(() => { // Используем ReferenceEquals, потому что нам нужно сравнить object и ISurvivalData по ссылке. // Это делаем, чтобы избежать приведения sender к ISurvivalData. var viewModel = ActorViewModels.SingleOrDefault(x => ReferenceEquals(x.Actor.Person.GetModule <ISurvivalModule>(), sender)); if (viewModel != null) { ActorViewModels.Remove(viewModel); } }, CancellationToken.None, TaskCreationOptions.None, _taskScheduler); }
private void Actor_DepositMined(object sender, MineDepositEventArgs e) { var actor = GetActorFromEventSender(sender); var depositViewModel = _staticObjectViewModels.Single(x => x.StaticObject == e.Deposit); var actorViewModel = ActorViewModels.Single(x => x.Actor == actor); actorViewModel.GraphicRoot.ProcessMine(depositViewModel.transform.position); var propContainer = e.Deposit.GetModule <IPropContainer>(); if (e.Result is SuccessMineDepositResult) { ShowFoundPropsModalOrNotFound(actor, propContainer); } }
private void ShowFoundPropsModalOrNotFound(IActor actor, IPropContainer propContainer) { var props = propContainer.Content.CalcActualItems(); if (props.Any()) { var containerPopupObj = _container.InstantiatePrefab(ContainerPopupPrefab, WindowCanvas.transform); var containerPopup = containerPopupObj.GetComponent <ContainerPopup>(); var transferMachine = new PropTransferMachine(actor.Person.GetModule <IInventoryModule>(), propContainer.Content); containerPopup.Init(transferMachine); } else { var indicator = Instantiate(FoundNothingIndicatorPrefab, transform); indicator.CurrentLanguage = _uiSettingService.CurrentLanguage; var actorViewModel = ActorViewModels.SingleOrDefault(x => x.Actor == actor); indicator.Init(actorViewModel); } }
private void CreateMonsterViewModels(IEnumerable <MapNodeVM> nodeViewModels) { var monsters = Sector.ActorManager.Items.Where(x => x.Person is MonsterPerson).ToArray(); foreach (var monsterActor in monsters) { var actorViewModelObj = _container.InstantiatePrefab(ActorPrefab, transform); var actorViewModel = actorViewModelObj.GetComponent <ActorViewModel>(); var actorGraphicObj = _container.InstantiatePrefab(MonoGraphicPrefab, actorViewModel.transform); var actorGraphic = actorGraphicObj.GetComponent <ActorGraphicBase>(); actorViewModel.SetGraphicRoot(actorGraphic); actorGraphic.transform.position = new Vector3(0, /*0.2f*/ 0, -0.27f); var graphicController = actorViewModel.gameObject.AddComponent <MonsterSingleActorGraphicController>(); graphicController.Actor = monsterActor; graphicController.Graphic = actorGraphic; var actorNodeVm = nodeViewModels.Single(x => ReferenceEquals(x.Node, monsterActor.Node)); var actorPosition = actorNodeVm.transform.position + new Vector3(0, 0, -1); actorViewModel.transform.position = actorPosition; actorViewModel.Actor = monsterActor; actorViewModel.Selected += EnemyActorVm_OnSelected; actorViewModel.MouseEnter += EnemyViewModel_MouseEnter; monsterActor.UsedAct += ActorOnUsedAct; monsterActor.Person.GetModule <ISurvivalModule>().Dead += Monster_Dead; var fowController = actorViewModel.gameObject.AddComponent <FowActorController>(); // Контроллеру тумана войны скармливаем только графику. // Потому что на основтой объект акёра завязаны блокировки (на перемещение, например). // Если основной объект создаст блокировку и будет отключен, // то он не сможет её снять в результате своих Update. // Это создаст всеобщую неснимаемую блокировку. fowController.Graphic = actorGraphic.gameObject; // Передаём коллайдер, чтобы в случае отключения графики скрытого актёра нельзя было выбрать. fowController.Collider = actorViewModel.GetComponent <Collider2D>(); ActorViewModels.Add(actorViewModel); } var humanActors = Sector.ActorManager.Items.Where(x => x.Person is HumanPerson && x.Person != _humanPlayer.MainPerson).ToArray(); foreach (var actor in humanActors) { var actorViewModelObj = _container.InstantiatePrefab(ActorPrefab, transform); var actorViewModel = actorViewModelObj.GetComponent <ActorViewModel>(); actorViewModel.PlayerState = _playerState; var actorGraphicObj = _container.InstantiatePrefab(HumanoidGraphicPrefab, actorViewModel.transform); var actorGraphic = actorGraphicObj.GetComponent <ActorGraphicBase>(); actorGraphic.transform.position = new Vector3(0, 0.2f, -0.27f); actorViewModel.SetGraphicRoot(actorGraphic); var graphicController = actorViewModel.gameObject.AddComponent <HumanActorGraphicController>(); graphicController.Actor = actor; graphicController.Graphic = actorGraphic; var actorNodeVm = NodeViewModels.Single(x => x.Node == actor.Node); var actorPosition = actorNodeVm.transform.position + new Vector3(0, 0, -1); actorViewModel.transform.position = actorPosition; actorViewModel.Actor = actor; actorViewModel.Selected += EnemyActorVm_OnSelected; actorViewModel.MouseEnter += EnemyViewModel_MouseEnter; actor.UsedAct += ActorOnUsedAct; actor.Person.GetModule <ISurvivalModule>().Dead += Monster_Dead; var fowController = actorViewModel.gameObject.AddComponent <FowActorController>(); // Контроллеру тумана войны скармливаем только графику. // Потому что на основтой объект акёра завязаны блокировки (на перемещение, например). // Если основной объект создаст блокировку и будет отключен, // то он не сможет её снять в результате своих Update. // Это создаст всеобщую неснимаемую блокировку. fowController.Graphic = actorGraphic.gameObject; // Передаём коллайдер, чтобы в случае отключения графики скрытого актёра нельзя было выбрать. fowController.Collider = actorViewModel.GetComponent <Collider2D>(); ActorViewModels.Add(actorViewModel); } }