public void RunCombatActUsageAnimation(ActDescription usedActDescription, IGraphNode targetNode) { if (!CanDraw) { return; } var serviceScope = ((LivGame)_game).ServiceProvider; var animationBlockerService = serviceScope.GetRequiredService <IAnimationBlockerService>(); var hexSize = MapMetrics.UnitSize / 2; var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)targetNode).OffsetCoords); var newPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); var targetSpritePosition = newPosition; var attackSoundEffectInstance = GetAttackSoundEffect(usedActDescription); var hitVisualEffect = GetAttackVisualEffect(targetNode, targetSpritePosition, usedActDescription); var stateEngine = new ActorMeleeAttackEngine( _rootSprite, targetSpritePosition, animationBlockerService, attackSoundEffectInstance, hitVisualEffect); AddStateEngine(stateEngine); }
private List <MapNodeVM> InitNodeViewModels() { var nodeVMs = new List <MapNodeVM>(); foreach (var node in _sector.Map.Nodes) { var mapNodeVm = Instantiate(MapNodePrefab, transform); var hexNode = (HexNode)node; var nodeWorldPositionParts = HexHelper.ConvertToWorld(hexNode.OffsetX, hexNode.OffsetY); var worldPosition = new Vector3(nodeWorldPositionParts[0], nodeWorldPositionParts[1] / 2); mapNodeVm.transform.position = worldPosition; mapNodeVm.Node = hexNode; var edges = _sector.Map.Edges.Where(x => x.Nodes.Contains(node)).ToArray(); var neighbors = (from edge in edges from neighbor in edge.Nodes where neighbor != node select neighbor).Cast <HexNode>().ToArray(); mapNodeVm.Edges = edges; mapNodeVm.Neighbors = neighbors; if (_sector.ExitNodes.Contains(node)) { mapNodeVm.IsExit = true; } mapNodeVm.OnSelect += MapNodeVm_OnSelect; nodeVMs.Add(mapNodeVm); } return(nodeVMs); }
private void Actor_UsedProp(object?sender, UsedPropEventArgs e) { var serviceScope = ((LivGame)_game).ServiceProvider; var animationBlockerService = serviceScope.GetRequiredService <IAnimationBlockerService>(); var visualizationContentStorage = serviceScope.GetRequiredService <IGameObjectVisualizationContentStorage>(); var consumableType = e.UsedProp.Scheme.Sid switch { "med-kit" => ConsumeEffectType.Heal, "water-bottle" => ConsumeEffectType.Drink, "packed-food" => ConsumeEffectType.Eat, _ => ConsumeEffectType.UseCommon }; var soundEffect = _personSoundStorage.GetConsumePropSound(consumableType); _actorStateEngine = new ActorCommonActionMoveEngine(_graphicsRoot.RootSprite, animationBlockerService, soundEffect?.CreateInstance()); var hexSize = MapMetrics.UnitSize / 2; var actorNode = (HexNode)(Actor.Node); var playerActorWorldCoords = HexHelper.ConvertToWorld(actorNode.OffsetCoords.X, actorNode.OffsetCoords.Y); var actorPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); const int START_EFFECT_Y = 24; var consumeEffect = new ConsumingEffect(visualizationContentStorage, actorPosition - (Vector2.UnitY * START_EFFECT_Y), consumableType ); _sectorViewModelContext.EffectManager.VisualEffects.Add(consumeEffect); }
public void Update() { var moveCommand = (MoveCommand)_moveCommand; var path = moveCommand.Path; foreach (Transform visualizationItem in transform) { Destroy(visualizationItem.gameObject); } if (_playerState.HoverViewModel is IMapNodeViewModel) { _lastPath = path; if (_lastPath != null) { foreach (var pathNode in _lastPath) { var hexPathNode = (HexNode)pathNode; var worldPosition = HexHelper.ConvertToWorld(hexPathNode.OffsetCoords); var item = Instantiate(VisualizationItemPrefab, transform); item.transform.position = new Vector3(worldPosition[0], worldPosition[1] / 2); } } } }
private List <MapNodeVM> InitNodeViewModels() { var map = _humanPlayer.SectorNode.Sector.Map; var nodeVMs = new List <MapNodeVM>(); foreach (var node in map.Nodes) { var mapNodeObj = _container.InstantiatePrefab(MapNodePrefab, transform); var mapNodeVm = mapNodeObj.GetComponent <MapNodeVM>(); var hexNode = (HexNode)node; var nodeWorldPositionParts = HexHelper.ConvertToWorld(hexNode.OffsetCoords); var worldPosition = new Vector3(nodeWorldPositionParts[0], nodeWorldPositionParts[1] / 2); mapNodeVm.transform.position = worldPosition; mapNodeVm.Node = hexNode; mapNodeVm.Neighbors = map.GetNext(node).Cast <HexNode>().ToArray(); mapNodeVm.LocaltionScheme = _sectorManager.CurrentSector.Scheme; if (map.Transitions.ContainsKey(node)) { mapNodeVm.IsExit = true; } mapNodeVm.OnSelect += MapNodeVm_OnSelect; mapNodeVm.MouseEnter += MapNodeVm_MouseEnter; nodeVMs.Add(mapNodeVm); } return(nodeVMs); }
public void Start() { var map = new LazyHexMap(100); foreach (var node in map.Nodes) { var hexObject = Instantiate(HexPrefab, Parent); var position = HexHelper.ConvertToWorld(node.Offset.X, node.Offset.Y); hexObject.transform.position = new Vector3(position[0], position[1] / 2, 0); var clientModel = hexObject.GetComponent <GlobalTerrainNode>(); clientModel.Init(node); _nodeModels.Add(clientModel); clientModel.Clicked += ClientModel_Clicked; } var army = new Army(map.Nodes.First()); var armyObject = Instantiate(ArmyPrefab, Parent); armyObject.Init(army); armyObject.Clicked += ArmyObject_Clicked; _armyModels.Add(armyObject); }
public StaticObjectViewModel(Game game, IStaticObject staticObject, SpriteBatch spriteBatch) { _game = game; StaticObject = staticObject; _spriteBatch = spriteBatch; var graphics = new StaticObjectGraphics(game, staticObject); var worldCoords = HexHelper.ConvertToWorld(((HexNode)StaticObject.Node).OffsetCoords); var hexSize = MapMetrics.UnitSize / 2; var staticObjectPosition = new Vector2( (int)Math.Round(worldCoords[0] * hexSize * Math.Sqrt(3), MidpointRounding.ToEven), (int)Math.Round(worldCoords[1] * hexSize * 2 / 2, MidpointRounding.ToEven) ); _rootSprite = new SpriteContainer { Position = staticObjectPosition }; var shadowTexture = _game.Content.Load <Texture2D>("Sprites/game-objects/simple-object-shadow"); _rootSprite.AddChild(new Sprite(shadowTexture) { Position = new Vector2(0, 0), Origin = new Vector2(0.5f, 0.5f), Color = new Color(Color.White, 0.5f) }); _rootSprite.AddChild(graphics); }
private void Actor_Moved(object sender, EventArgs e) { _moveCounter = 0; var actorNode = (HexNode)Actor.Node; var worldPositionParts = HexHelper.ConvertToWorld(actorNode.OffsetX, actorNode.OffsetY); _targetPosition = new Vector3(worldPositionParts[0], worldPositionParts[1] / 2, -1); }
private void Actor_OpenedContainer(object sender, OpenContainerEventArgs e) { var containerNode = (HexNode)e.Container.Node; var worldPositionParts = HexHelper.ConvertToWorld(containerNode.OffsetX, containerNode.OffsetY); var targetPosition = new Vector3(worldPositionParts[0], worldPositionParts[1] / 2, -1); GraphicRoot.ProcessInteractive(targetPosition); }
private void Actor_Moved(object?sender, ActorMoveEventArgs e) { var hexSize = MapMetrics.UnitSize / 2; var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)Actor.Node).OffsetCoords); var newPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); if (!CanDraw) { _rootSprite.Position = newPosition; return; } var serviceScope = ((LivGame)_game).ServiceProvider; var animationBlockerService = serviceScope.GetRequiredService <IAnimationBlockerService>(); SoundEffectInstance?moveSoundEffectInstance = null; var player = serviceScope.GetRequiredService <IPlayer>(); if (sender is IActor actor && actor.Person == player.MainPerson) { // Sound steps of main person only to prevent infinite steps loop. var moveSoundEffect = _personSoundStorage.GetActivitySound(PersonActivityEffectType.Move); moveSoundEffectInstance = moveSoundEffect?.CreateInstance(); } if (!e.Forced) { var moveEngine = new ActorMoveEngine( _rootSprite, _graphicsRoot.RootSprite, _shadowSprite, newPosition, animationBlockerService, moveSoundEffectInstance); AddStateEngine(moveEngine); } else { var pushEngine = new ActorPushEngine( _rootSprite, _graphicsRoot.RootSprite, _shadowSprite, newPosition, animationBlockerService, moveSoundEffectInstance); AddStateEngine(pushEngine); } }
public float[] ConvertToWorldTest(int offsetX, int offsetY) { // ARRANGE // ACT var factCubeCoords = HexHelper.ConvertToWorld(offsetX, offsetY); // ASSERT return(factCubeCoords); }
private void Actor_UsedAct(object?sender, UsedActEventArgs e) { var stats = e.TacticalAct.Stats; if (stats is null) { throw new InvalidOperationException("The act has no stats to select visualization."); } Debug.WriteLine(e.TacticalAct); if (CanDraw) { if (stats.Effect == TacticalActEffectType.Damage && stats.IsMelee) { var serviceScope = ((LivGame)_game).ServiceProvider; var animationBlockerService = serviceScope.GetRequiredService <IAnimationBlockerService>(); var hexSize = MapMetrics.UnitSize / 2; var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)e.TargetNode).OffsetCoords); var newPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); var targetSpritePosition = newPosition; var attackSoundEffectInstance = GetSoundEffect(e.TacticalAct.Stats); _actorStateEngine = new ActorMeleeAttackEngine( _rootSprite, targetSpritePosition, animationBlockerService, attackSoundEffectInstance); // Selection actors only prevent error when monster stays on loot bag. var targetGameObject = _sectorViewModelContext.GameObjects.SingleOrDefault(x => x is IActorViewModel && x.Node == e.TargetNode); if (targetGameObject is null) { // This means the attacker is miss. // This situation can be then the target actor moved before the attack reaches the target. } else { var hitEffect = new HitEffect((LivGame)_game, targetSpritePosition + targetGameObject.HitEffectPosition, targetSpritePosition - _rootSprite.Position); _sectorViewModelContext.EffectManager.VisualEffects.Add(hitEffect); } } } }
private void Actor_Moved(object sender, EventArgs e) { _moveCounter = 0; var actorHexNode = (HexNode)Actor.Node; var worldPositionParts = HexHelper.ConvertToWorld(actorHexNode.OffsetX, actorHexNode.OffsetY); _targetPosition = new Vector3(worldPositionParts[0], worldPositionParts[1] / 2, actorHexNode.OffsetY - 0.26f); _moveCommandBlocker = new MoveCommandBlocker(); _commandBlockerService.AddBlocker(_moveCommandBlocker); GraphicRoot.ProcessMove(_targetPosition); }
private void ResetActorRootSpritePosition() { var hexSize = MapMetrics.UnitSize / 2; var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)Actor.Node).OffsetCoords); var newPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); _rootSprite.Position = newPosition; }
private void UpdateTargetPosition(IActorViewModel target) { var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)target.Actor.Node).OffsetCoords); var hexSize = MapMetrics.UnitSize / 2; var actorPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); _targetPosition = actorPosition; }
public StaticObjectViewModel(Game game, IStaticObject staticObject, SpriteBatch spriteBatch, bool createHighlighted = false) { _game = game; StaticObject = staticObject; _spriteBatch = spriteBatch; var graphics = new StaticObjectGraphics(game, staticObject); var worldCoords = HexHelper.ConvertToWorld(((HexNode)StaticObject.Node).OffsetCoords); var hexSize = MapMetrics.UnitSize / 2; var staticObjectPosition = new Vector2( (int)Math.Round(worldCoords[0] * hexSize * Math.Sqrt(HIGHLIGHT_DURATION_SECONDS), MidpointRounding.ToEven), (int)Math.Round(worldCoords[1] * hexSize * 2 / 2, MidpointRounding.ToEven) ); _rootSprite = new SpriteContainer { Position = staticObjectPosition }; var hasNoShadow = StaticObject.Purpose == PropContainerPurpose.Puddle || StaticObject.Purpose == PropContainerPurpose.Pit; if (!hasNoShadow) { var shadowTexture = _game.Content.Load <Texture2D>("Sprites/game-objects/simple-object-shadow"); _rootSprite.AddChild(new Sprite(shadowTexture) { Position = new Vector2(0, 0), Origin = new Vector2(0.5f, 0.5f), Color = new Color(Color.White, 0.5f) }); } _rootSprite.AddChild(graphics); if (createHighlighted) { _highlightCounter = HIGHLIGHT_DURATION_SECONDS; } }
public void RunDamageReceivedAnimation(IGraphNode attackerNode) { var serviceScope = ((LivGame)_game).ServiceProvider; var animationBlockerService = serviceScope.GetRequiredService <IAnimationBlockerService>(); var soundEffectInstance = GetPersonImpactSoundEffect(Actor.Person); var hexSize = MapMetrics.UnitSize / 2; var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)attackerNode).OffsetCoords); var attackerPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); var moveEngine = new ActorDamagedEngine(_graphicsRoot, _rootSprite, attackerPosition, animationBlockerService, soundEffectInstance); AddStateEngine(moveEngine); }
private static void DrawAllNodes(IEnumerable <HexNode> nodes, Bitmap bitmap, ImageInfo info) { using (var graphics = Graphics.FromImage(bitmap)) { Clear(bitmap, graphics); DrawAxisNumbers(info, graphics); foreach (var node in nodes) { var coords = HexHelper.ConvertToWorld(node.OffsetCoords); var x = (coords[0] - info.LeftCoord) * CELLSIZE; var y = (coords[1] - info.BottomCoord) * CELLSIZE; var cellBrush = Brushes.White; graphics.FillEllipse(cellBrush, x + MARGIN, y + MARGIN, CELLSIZE, CELLSIZE); } } }
public void Follow(IActorViewModel target, Game game) { var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)target.Actor.Node).OffsetCoords); var hexSize = MapMetrics.UnitSize / 2; var actorPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); var position = Matrix.CreateTranslation( -actorPosition.X, -actorPosition.Y, 0); var offset = Matrix.CreateTranslation( (float)game.GraphicsDevice.Viewport.Width / 2, (float)game.GraphicsDevice.Viewport.Height / 2, 0); Transform = position * offset; }
public override void Update(GameTime gameTime) { if (_actorStateEngine != null) { _actorStateEngine.Update(gameTime); if (_actorStateEngine.IsComplete) { _actorStateEngine = new ActorIdleEngine(_graphicsRoot.RootSprite); var hexSize = MapMetrics.UnitSize / 2; var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)Actor.Node).OffsetCoords); var newPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); _rootSprite.Position = newPosition; } } var keyboard = Keyboard.GetState(); _graphicsRoot.ShowOutlined = keyboard.IsKeyDown(Keys.LeftAlt); }
private void UpdateSpriteMatrix(GameTime gameTime) { _updateCounter -= gameTime.ElapsedGameTime.TotalSeconds; if (_updateCounter > 0) { return; } _updateCounter = MAP_UPDATE_DELAY_SECONDS; if (_player.MainPerson is null) { throw new InvalidOperationException(); } var fowData = _player.MainPerson.GetModule <IFowData>(); var visibleFowNodeData = fowData.GetSectorFowData(_sector); if (visibleFowNodeData is null) { throw new InvalidOperationException(); } var materializedNodes = visibleFowNodeData.Nodes.ToArray(); Parallel.ForEach(materializedNodes, fowNode => { var node = (HexNode)fowNode.Node; Color nodeColor; if (_uiState.HoverViewModel != null && node == _uiState.HoverViewModel.Item) { nodeColor = Color.CornflowerBlue; } else { nodeColor = Color.White; } if (fowNode.State != SectorMapNodeFowState.Observing) { nodeColor = Color.Lerp(nodeColor, new Color(0, 0, 0, 0), 0.5f); } if (!_hexSprites.TryGetValue(node.OffsetCoords, out var currentHexSprite)) { var worldCoords = HexHelper.ConvertToWorld(node.OffsetCoords); var hexSize = MapMetrics.UnitSize / 2; var hexTextureIndex = node.GetHashCode() % 4; var hexTextureIndexX = hexTextureIndex / 2; var hexTextureIndexY = hexTextureIndex % 2; // Remember. Hex width is less that size (radius). // It equals R*Sqrt(3)/2. So sprite width is R*Sqrt(3)/2*2 or R*Sqrt(3). It's about 28 pixels. // You should make sprite 28*16. var hexSprite = new Sprite(_hexSprite) { SourceRectangle = new Rectangle(hexTextureIndexX * 28, hexTextureIndexY * 16, 28, 16) }; var hexSpriteContainer = new SpriteContainer { Position = new Vector2( (float)(worldCoords[0] * hexSize * Math.Sqrt(3)), worldCoords[1] * hexSize * 2 / 2 ) }; hexSpriteContainer.AddChild(hexSprite); if (_sector.Map.Transitions.TryGetValue(fowNode.Node, out var transition)) { if (transition.SectorNode.Biome.LocationScheme.Sid == "dungeon" || transition.SectorNode.Biome.LocationScheme.Sid == "elder-temple") { var transitionMarkerSprite = new Sprite(_hexMarkerTextures) { SourceRectangle = new Rectangle(28, 0, 28, 16) }; hexSpriteContainer.AddChild(transitionMarkerSprite); } else { var transitionMarkerSprite = new Sprite(_hexMarkerTextures) { SourceRectangle = new Rectangle(0, 0, 28, 16) }; hexSpriteContainer.AddChild(transitionMarkerSprite); } } _hexSprites.AddOrUpdate(node.OffsetCoords, hexSpriteContainer, (offsetCoords, sprite) => { return(sprite); }); currentHexSprite = hexSpriteContainer; } currentHexSprite.Color = nodeColor; }); }
private void Start() { var map = new FixedMap(25); foreach (var node in map.Nodes) { var hexObject = Instantiate(HexPrefab, Parent); var position = HexHelper.ConvertToWorld(node.Offset.X, node.Offset.Y); hexObject.transform.position = new Vector3(position[0] * 20, position[1] * 20, 0); hexObject.Init(node); _nodeModels.Add(hexObject); hexObject.Clicked += HexObject_Clicked; if (UnityEngine.Random.Range(0, 100) > 70) { for (var i = 0; i < UnityEngine.Random.Range(3, 7); i++) { var wallObject = Instantiate(WallPrefab, hexObject.transform); wallObject.transform.localPosition = UnityEngine.Random.insideUnitCircle * 5; } } } var nameGenerator = new IdNameGenerator(); for (var i = 0; i < 6; i++) { var node = map.Nodes.Skip(i * 3 + 1).First(); var personList = new List <ICombatPerson>(); for (var j = 0; j < 5; j++) { var person = new CombatPerson(nameGenerator); personList.Add(person); } var squad = new CombatSquad(node, personList.ToArray(), i < 2 ? Player.Human : Player.Cpu); _combatService.SquadManager.Add(squad); var squadObject = Instantiate(CombatSquadPrefab, Parent); var personModelList = new List <CombatPersonModel>(); var formationSize = Mathf.Sqrt(squad.Persons.Length) + 1; var personX = 0; var personY = 0; foreach (var combatPerson in squad.Persons) { var combatPersonModel = Instantiate(CompatPersonPrefab, squadObject.transform); personModelList.Add(combatPersonModel); personX++; if (personX >= formationSize) { personX = 0; personY++; } combatPersonModel.transform.position = new Vector3(personX * 1.5f, personY * 1.5f); combatPersonModel.Clicked += CombatPersonModelOnClicked; combatPersonModel.HoverEnter += CombatPersonModelOnHoverEnter; combatPersonModel.HoverExit += CombatPersonModelOnHoverExit; combatPersonModel.Init(combatPerson); } squadObject.Init(squad, personModelList.ToArray()); _squadModels.Add(squadObject); } _combatEventBus.EventRegistered += CombatEventBusOnEventRegistered; }
private async void Start() { if (_globeManager.Globe == null) { _globeManager.Globe = await _globeGenerator.GenerateGlobeAsync(); var firstLocality = _globeManager.Globe.Localities.First(); _player.Terrain = firstLocality.Cell; var createdRegion = await _globeGenerator.GenerateRegionAsync(_globeManager.Globe, firstLocality.Cell); _globeManager.Regions[_player.Terrain] = createdRegion; var firstNode = (GlobeRegionNode)createdRegion.Nodes.First(); _player.GlobeNode = firstNode; } var currentGlobeCell = _player.Terrain; _region = _globeManager.Regions[currentGlobeCell]; _locationNodeViewModels = new List <MapLocation>(100); foreach (GlobeRegionNode globeRegionNode in _region.Nodes) { var worldCoords = HexHelper.ConvertToWorld(globeRegionNode.OffsetX, globeRegionNode.OffsetY); var locationObject = _container.InstantiatePrefab(LocationPrefab, transform); locationObject.transform.position = new Vector3(worldCoords[0], worldCoords[1], 0); var locationViewModel = locationObject.GetComponent <MapLocation>(); locationViewModel.Node = globeRegionNode; _locationNodeViewModels.Add(locationViewModel); locationViewModel.OnSelect += LocationViewModel_OnSelect; locationViewModel.OnHover += LocationViewModel_OnHover; } var openNodeViewModels = new List <MapLocation>(_locationNodeViewModels); while (openNodeViewModels.Any()) { var currentNodeViewModel = openNodeViewModels[0]; openNodeViewModels.Remove(currentNodeViewModel); var neighbors = _region.GetNext(currentNodeViewModel.Node); var neighborViewModels = openNodeViewModels.Where(x => neighbors.Contains(x.Node)).ToArray(); foreach (var neibourNodeViewModel in neighborViewModels) { var connectorObject = _container.InstantiatePrefab(ConnectorPrefab, transform); var connectorViewModel = connectorObject.GetComponent <MapLocationConnector>(); connectorViewModel.gameObject1 = currentNodeViewModel.gameObject; connectorViewModel.gameObject2 = neibourNodeViewModel.gameObject; } } var playerGroupNodeViewModel = _locationNodeViewModels.Single(x => x.Node == _player.GlobeNode); var groupObject = _container.InstantiatePrefab(HumanGroupPrefab, transform); _groupViewModel = groupObject.GetComponent <GroupVM>(); _groupViewModel.CurrentLocation = playerGroupNodeViewModel; groupObject.transform.position = playerGroupNodeViewModel.transform.position; Camera.Target = groupObject; _player.GlobeNodeChanged += HumanPlayer_GlobeNodeChanged; MoveGroupViewModel(_player.GlobeNode); }
private async void Start() { //TODO Разобраться, почему остаются блоки от перемещения при использовании перехода _commandBlockerService.DropBlockers(); if (_globeManager.Globe == null) { if (!_progressStorageService.LoadGlobe()) { var globeGenerationResult = await _globeGenerator.GenerateGlobeAsync(); _globeManager.Globe = globeGenerationResult.Globe; _globeManager.GlobeGenerationHistory = globeGenerationResult.History; var startCell = _globeManager.Globe.StartProvince; _player.Terrain = startCell; var createdRegion = await CreateRegionAsync(_globeManager.Globe, _player.Terrain, _globeGenerator, _progressStorageService); await CreateNeighborRegionsAsync(_player.Terrain.Coords, _globeManager, _globeGenerator, _progressStorageService); _globeManager.Regions[_player.Terrain] = createdRegion; var startNode = createdRegion.RegionNodes.Single(x => x.IsStart); _player.GlobeNode = startNode; startNode.ObservedState = GlobeNodeObservedState.Visited; _globeModalManager.ShowHistoryBookModal(); } else { _globeManager.GlobeGenerationHistory = new GlobeGenerationHistory(); if (!_progressStorageService.LoadPlayer()) { var startCell = _globeManager.Globe.StartProvince; _player.Terrain = startCell; } } } var currentGlobeCell = _player.Terrain; if (!_globeManager.Regions.TryGetValue(currentGlobeCell, out var currentRegion)) { var createdRegion = await CreateRegionAsync(_globeManager.Globe, currentGlobeCell, _globeGenerator, _progressStorageService); _globeManager.Regions[_player.Terrain] = createdRegion; } // Создание соседних регионов await CreateNeighborRegionsAsync(_player.Terrain.Coords, _globeManager, _globeGenerator, _progressStorageService); Debug.Log($"Current: {currentGlobeCell}"); Debug.Log($"Current: {_globeManager.Globe.HomeProvince}"); _region = currentRegion; // Создание визуализации узлов провинции. _locationNodeViewModels = new List <MapLocation>(100); foreach (GlobeRegionNode globeRegionNode in _region.Nodes) { var worldCoords = HexHelper.ConvertToWorld(globeRegionNode.OffsetX + _player.Terrain.Coords.X * 20, globeRegionNode.OffsetY + _player.Terrain.Coords.Y * 20); var locationObject = _container.InstantiatePrefab(LocationPrefab, transform); locationObject.transform.position = new Vector3(worldCoords[0], worldCoords[1], 0); var locationViewModel = locationObject.GetComponent <MapLocation>(); locationViewModel.Node = globeRegionNode; locationViewModel.ParentRegion = _region; _locationNodeViewModels.Add(locationViewModel); locationViewModel.OnSelect += LocationViewModel_OnSelect; locationViewModel.OnHover += LocationViewModel_OnHover; } // Создание коннекторов между узлами провинции. var openNodeViewModels = new List <MapLocation>(_locationNodeViewModels); while (openNodeViewModels.Any()) { var currentNodeViewModel = openNodeViewModels[0]; openNodeViewModels.Remove(currentNodeViewModel); var neighbors = _region.GetNext(currentNodeViewModel.Node); var neighborViewModels = openNodeViewModels.Where(x => neighbors.Contains(x.Node)).ToArray(); foreach (var neibourNodeViewModel in neighborViewModels) { CreateConnector(currentNodeViewModel, neibourNodeViewModel); } } // Создание визуализаций соседних провинций var currentRegionBorders = _region.RegionNodes.Where(x => x.IsBorder).ToArray(); // TODO в открытые можно помещать только бордюр для экономии. openNodeViewModels = new List <MapLocation>(_locationNodeViewModels); var currentBorderNodes = currentRegion.Nodes.OfType <GlobeRegionNode>().Where(x => x.IsBorder).ToArray(); for (var offsetX = -1; offsetX <= 1; offsetX++) { for (var offsetY = -1; offsetY <= 1; offsetY++) { if (offsetX == 0 && offsetY == 0) { // Это нулевое смещение от текущего элемента. // Пропускаем, т.к. текущий элемент уже есть. continue; } var terrainX = _player.Terrain.Coords.X + offsetX; var terrainY = _player.Terrain.Coords.Y + offsetY; if (_globeManager.Globe.Terrain.GetLowerBound(0) <= terrainX && terrainX <= _globeManager.Globe.Terrain.GetUpperBound(0) && _globeManager.Globe.Terrain[0].GetLowerBound(0) <= terrainY && terrainY <= _globeManager.Globe.Terrain[0].GetUpperBound(0)) { var terrainCell = _globeManager.Globe.Terrain[terrainX][terrainY]; var neighborRegion = _globeManager.Regions[terrainCell]; // Ищем узел текущей провинции, являющийся соседним с узлом соседней провинции. var neighborBorderNodes = neighborRegion.Nodes.OfType <GlobeRegionNode>().Where(x => x.IsBorder); foreach (var neighborBorderNode in neighborBorderNodes) { var transitionNodes = RegionTransitionHelper.GetNeighborBorderNodes(neighborBorderNode, terrainCell, currentRegionBorders, _player.Terrain); if (!transitionNodes.Any()) { // Этот узел соседней провинции не имеет переходов в текущую. // Соответственно, из текущей провинции никто не будет иметь переходов в этот узел соседней провинции. // Значит его можно вообще не отрисовывать. continue; } var worldCoords = HexHelper.ConvertToWorld(neighborBorderNode.OffsetX + terrainX * 20, neighborBorderNode.OffsetY + terrainY * 20); var locationObject = _container.InstantiatePrefab(LocationPrefab, transform); locationObject.transform.position = new Vector3(worldCoords[0], worldCoords[1], 0); var locationViewModel = locationObject.GetComponent <MapLocation>(); locationViewModel.Node = neighborBorderNode; locationViewModel.ParentRegion = neighborRegion; locationViewModel.OtherRegion = true; _locationNodeViewModels.Add(locationViewModel); locationViewModel.OnSelect += LocationViewModel_OnSelect; locationViewModel.OnHover += LocationViewModel_OnHover; // Создаём коннекторы от всех пограничных узлов, // имеющий переходв в текущий узел соседней провинции. var openTransitionNodes = openNodeViewModels.Where(x => transitionNodes.Contains(x.Node)); foreach (var openTransitionNode in openTransitionNodes) { CreateConnector(openTransitionNode, locationViewModel); } } } } } if (_player.MainPerson == null) { if (!_progressStorageService.LoadPerson()) { _player.MainPerson = _humanPersonFactory.Create(); } } var playerGroupNodeViewModel = _locationNodeViewModels.Single(x => x.Node == _player.GlobeNode); var groupObject = _container.InstantiatePrefab(HumanGroupPrefab, transform); _groupViewModel = groupObject.GetComponent <GroupVM>(); _groupViewModel.CurrentLocation = playerGroupNodeViewModel; groupObject.transform.position = playerGroupNodeViewModel.transform.position; Camera.Target = groupObject; Camera.GetComponent <GlobalFollowCamera>().SetPosition(groupObject.transform); var nodes = _locationNodeViewModels.Select(x => x.Node); var centerLocationNode = GlobeHelper.GetCenterLocationNode(nodes); var centerLocationNodeViewModel = _locationNodeViewModels .Single(nodeViewModel => nodeViewModel.Node.OffsetX == centerLocationNode.OffsetX && nodeViewModel.Node.OffsetY == centerLocationNode.OffsetY); MapBackground.transform.position = centerLocationNodeViewModel.transform.position; _player.GlobeNodeChanged += HumanPlayer_GlobeNodeChanged; MoveGroupViewModel(_player.GlobeNode); }
public ActorViewModel( IActor actor, GameObjectParams gameObjectParams) { Actor = actor; _game = gameObjectParams.Game ?? throw new ArgumentException($"{nameof(gameObjectParams.Game)} is not defined.", nameof(gameObjectParams)); _sectorViewModelContext = gameObjectParams.SectorViewModelContext ?? throw new ArgumentException( $"{nameof(gameObjectParams.SectorViewModelContext)} is not defined.", nameof(gameObjectParams)); _personSoundStorage = gameObjectParams.PersonSoundStorage ?? throw new ArgumentException( $"{nameof(gameObjectParams.PersonSoundStorage)} is not defined.", nameof(gameObjectParams)); _gameObjectVisualizationContentStorage = gameObjectParams.GameObjectVisualizationContentStorage ?? throw new ArgumentException( $"{nameof(gameObjectParams.GameObjectVisualizationContentStorage)} is not defined.", nameof(gameObjectParams)); _spriteBatch = gameObjectParams.SpriteBatch ?? throw new ArgumentException($"{nameof(gameObjectParams.SpriteBatch)} is not defined.", nameof(gameObjectParams)); if (gameObjectParams.PersonVisualizationContentStorage is null) { throw new ArgumentException( $"{nameof(gameObjectParams.PersonVisualizationContentStorage)} is not defined.", nameof(gameObjectParams)); } var equipmentModule = Actor.Person.GetModuleSafe <IEquipmentModule>(); var shadowTexture = _game.Content.Load <Texture2D>("Sprites/game-objects/simple-object-shadow"); _rootSprite = new SpriteContainer(); _shadowSprite = new Sprite(shadowTexture) { Position = new Vector2(0, 0), Origin = new Vector2(0.5f, 0.5f), Color = new Color(Color.White, 0.5f) }; _rootSprite.AddChild(_shadowSprite); var isHumanGraphics = Actor.Person is HumanPerson; if (isHumanGraphics) { if (equipmentModule is not null) { var graphicsRoot = new HumanoidGraphics(equipmentModule, gameObjectParams.PersonVisualizationContentStorage); _rootSprite.AddChild(graphicsRoot); _graphicsRoot = graphicsRoot; } else { // There is no cases when human person hasn't equipment module. // It can be empty module to show "naked" person in the future. throw new InvalidOperationException("Person has no IEquipmentModule."); } } else { var monsterPerson = Actor.Person as MonsterPerson; SpriteContainer?graphics = null; switch (monsterPerson.Scheme.Sid) { case "predator": graphics = new AnimalGraphics(gameObjectParams.PersonVisualizationContentStorage); break; case "warthog": graphics = new MonoGraphics("warthog", gameObjectParams.PersonVisualizationContentStorage); break; case "predator-meat": graphics = new AnimalGraphics(gameObjectParams.PersonVisualizationContentStorage); break; case "skeleton": graphics = new MonoGraphics("skeleton", gameObjectParams.PersonVisualizationContentStorage); break; case "skeleton-equipment": graphics = new MonoGraphics("skeleton-equipment", gameObjectParams.PersonVisualizationContentStorage); break; case "gallbladder": graphics = new MonoGraphics("gallbladder", gameObjectParams.PersonVisualizationContentStorage); break; } _rootSprite.AddChild(graphics); _graphicsRoot = (IActorGraphics)graphics; } var hexSize = MapMetrics.UnitSize / 2; var playerActorWorldCoords = HexHelper.ConvertToWorld(((HexNode)Actor.Node).OffsetCoords); var newPosition = new Vector2( (float)(playerActorWorldCoords[0] * hexSize * Math.Sqrt(3)), playerActorWorldCoords[1] * hexSize * 2 / 2 ); _rootSprite.Position = newPosition; Actor.Moved += Actor_Moved; Actor.UsedProp += Actor_UsedProp; Actor.PropTransferPerformed += Actor_PropTransferPerformed; Actor.BeginTransitionToOtherSector += Actor_BeginTransitionToOtherSector; if (Actor.Person.HasModule <IEquipmentModule>()) { Actor.Person.GetModule <IEquipmentModule>().EquipmentChanged += PersonEquipmentModule_EquipmentChanged; } if (Actor.Person.HasModule <ISurvivalModule>()) { Actor.Person.GetModule <ISurvivalModule>().Dead += PersonSurvivalModule_Dead; } _actorStateEngineList = new List <IActorStateEngine> { new ActorIdleEngine(_graphicsRoot.RootSprite) }; }