/// <summary> /// move using the entities heading /// </summary> /// <returns></returns> private BehaviorReturnCode moveViaHeading() { Heading heading = (Heading)w_HeadingMapper.get(w_ThisEntity); Position position = (Position)w_PositionMapper.get(w_ThisEntity); Velocity velocity = (Velocity)w_VelocityMapper.get(w_ThisEntity); Vector2 pos = position.Pos;// +position.Offset; pos += heading.getHeading() * velocity.Vel; position.Pos = pos; w_Moved = true; SpatialPartition spatial = (SpatialPartition)w_SpatialMapper.get(w_Spatial); if (w_LastNode != null) { w_LastNode.Contents.Remove(w_ThisEntity); } w_LastNode = spatial.QuadTree.setContentAtLocation(w_ThisEntity, pos + new Vector2(16, 16)); return(BehaviorReturnCode.Success); }
/// <summary> /// perform all needed initialization /// </summary> /// <returns>whether initialization was a success or not</returns> private BehaviorReturnCode initialize() { Position position = (Position)w_PositionMapper.get(w_ThisEntity); w_Spatial = w_ECSInstance.tag_manager.get_entity_by_tag("SPATIAL"); SpatialPartition spatial = (SpatialPartition)w_SpatialMapper.get(w_Spatial); Vector2 pos = position.Pos; Vector2 dir = new Vector2((float)w_Random.NextDouble() * 2 - 1, (float)w_Random.NextDouble() * 2 - 1); dir.Normalize(); Heading heading = (Heading)w_HeadingMapper.get(w_ThisEntity); heading.setHeading(dir); w_LastNode = spatial.QuadTree.setContentAtLocation(w_ThisEntity, pos + new Vector2(16, 16)); w_Camera = w_ECSInstance.tag_manager.get_entity_by_tag("CAMERA"); w_EntityFaction = (Factions)w_FactionMapper.get(w_ThisEntity); return(BehaviorReturnCode.Success); }
public EntityThread(ulong threadIndex, EntityThreadRepository entityThreadRepository, ClientThreadRepository clientThreadRepository, SpatialPartition spatialPartition, int syncRate, bool netOwnerEvents, Action <IClient, IEntity, LinkedList <string> > onEntityCreate, Action <IClient, IEntity> onEntityRemove, Action <IClient, IEntity, LinkedList <string> > onEntityDataChange, Action <IClient, IEntity, Vector3> onEntityPositionChange, Action <IClient, IEntity> onEntityClearCache, Action <IClient, IEntity, bool> onEntityNetOwnerChange) { this.threadIndex = threadIndex; this.entityThreadRepository = entityThreadRepository ?? throw new ArgumentException("entityThreadRepository should not be null."); this.clientThreadRepository = clientThreadRepository; this.spatialPartition = spatialPartition ?? throw new ArgumentException("spatialPartition should not be null."); this.syncRate = syncRate; this.netOwnerEvents = netOwnerEvents; this.onEntityCreate = onEntityCreate ?? throw new ArgumentException("onEntityCreate should not be null."); this.onEntityRemove = onEntityRemove ?? throw new ArgumentException("onEntityRemove should not be null."); this.onEntityDataChange = onEntityDataChange ?? throw new ArgumentException("onEntityDataChange should not be null."); this.onEntityPositionChange = onEntityPositionChange ?? throw new ArgumentException("onEntityPositionChange should not be null."); this.onEntityClearCache = onEntityClearCache ?? throw new ArgumentException("onEntityPositionChange should not be null."); this.onEntityNetOwnerChange = onEntityNetOwnerChange ?? throw new ArgumentException("onEntityNetOwnerChange should not be null."); thread = new Thread(OnLoop) { IsBackground = true }; thread.Start(); }
public EntityThread(EntityThreadRepository entityThreadRepository, ClientThreadRepository clientThreadRepository, SpatialPartition spatialPartition, int syncRate, Action <IClient, IEntity, LinkedList <string> > onEntityCreate, Action <IClient, IEntity> onEntityRemove, Action <IClient, IEntity, LinkedList <string> > onEntityDataChange, Action <IClient, IEntity, Vector3> onEntityPositionChange, Action <IClient, IEntity> onEntityClearCache) { if (spatialPartition == null) { throw new ArgumentException("spatialPartition should not be null."); } if (entityThreadRepository == null) { throw new ArgumentException("entityThreadRepository should not be null."); } if (onEntityCreate == null) { throw new ArgumentException("onEntityCreate should not be null."); } if (onEntityRemove == null) { throw new ArgumentException("onEntityRemove should not be null."); } if (onEntityDataChange == null) { throw new ArgumentException("onEntityDataChange should not be null."); } if (onEntityPositionChange == null) { throw new ArgumentException("onEntityPositionChange should not be null."); } if (onEntityClearCache == null) { throw new ArgumentException("onEntityPositionChange should not be null."); } thread = new Thread(OnLoop) { IsBackground = true }; thread.Start(); this.entityThreadRepository = entityThreadRepository; this.clientThreadRepository = clientThreadRepository; this.spatialPartition = spatialPartition; this.syncRate = syncRate; this.onEntityCreate = onEntityCreate; this.onEntityRemove = onEntityRemove; this.onEntityDataChange = onEntityDataChange; this.onEntityPositionChange = onEntityPositionChange; this.onEntityClearCache = onEntityClearCache; }
// Use this for initialization void Start() { if (instance == null) { instance = this; } GenerateSpatialPartition(); }
internal static void GetAdjacentTiles(List <PartitionTile> tileList, Vector2 position, bool includeLargeObjects = true) { SpatialPartition p = FetchPartition(position); p?.GetAdjacentTiles(tileList, position - p.Position); if (includeLargeObjects) { tileList.Add(largeObjectTile); } }
private static SpatialPartition CreateNewPartition(Point position, bool active = false) { Point newPos = ToPartitionPoint(position); Rectangle bounds = new Rectangle(newPos.X, newPos.Y, PartitionSize, PartitionSize); SpatialPartition partition = new SpatialPartition(TileSize, bounds); partitionPool.Add(partition); return(active ? TakeFromPool(position) : partition); }
public ParticleLightManager( ParticleSystem <T> system, IEnumerable <LightingEnvironment> lightingEnvironments, UpdaterDelegate updater ) { System = system; _Partition = new SpatialPartition <Sector>(system.Subdivision, (sectorIndex) => new Sector(this, sectorIndex)); LightingEnvironments = lightingEnvironments; Updater = updater; }
public SpatialPartition GeneratePlanetPartition() { var icosahedron = Utils.GenerateIcosahedron(); // TODO: Change these 1000s with a global scale; for (var i = 0; i < icosahedron.faces.Count; ++i) { var face = icosahedron.faces[i]; var p0 = icosahedron.nodes[face.n[0]].p /** 1000*/; var p1 = icosahedron.nodes[face.n[1]].p /** 1000*/; var p2 = icosahedron.nodes[face.n[2]].p /** 1000*/; var center = (p0 + p1 + p2) / 3; var radius = Math.Max(Vector3.Distance(center, p0), Math.Max(Vector3.Distance(center, p2), Vector3.Distance(center, p2))); face.sphereCenter = center; face.sphereRadius = radius; face.children = new List<Tile>(); } var unparentedTiles = new List<Tile>(); var maxDistanceFromOrigin = 0f; for(var i = 0; i < this.tiles.Count; ++i) { var tile = this.tiles[i]; maxDistanceFromOrigin = Math.Max(maxDistanceFromOrigin, tile.averagePosition.magnitude + tile.radius); var parentFound = false; for (var j = 0; j < icosahedron.faces.Count; ++j) { var face = icosahedron.faces[j]; var distance = Vector3.Distance(tile.averagePosition, face.sphereCenter) + tile.radius; if (distance < face.sphereRadius) { face.children.Add(tile); parentFound = true; break; } } if (!parentFound) { unparentedTiles.Add(tile); } } SpatialPartition rootPartition = new SpatialPartition(Vector3.zero, maxDistanceFromOrigin, new List<SpatialPartition>(), unparentedTiles); for(var i = 0; i < icosahedron.faces.Count; ++i) { var face = icosahedron.faces[i]; rootPartition.partitions.Add(new SpatialPartition(face.sphereCenter, face.sphereRadius, new List<SpatialPartition>(), face.children)); } this.partition = rootPartition; return rootPartition; }
private static void ReturnToPool(SpatialPartition partition) { partitions.Remove(partition); // Return the partition to the pool, if there's enough room. if (partitionPool.Count + 1 < MaxPoolSize) { partitionPool.Add(partition); } partition.IsActive = false; }
public static void GetFromRegionRaw <T>(QuickList <IPartitionObject> existingList, Rectangle regionBounds) where T : IPartitionObject { for (int i = 0; i < partitions.Count; i++) { SpatialPartition partition = partitions.Array[i]; if (partition.Bounds.Intersects(regionBounds)) { partition.GetFromRegionRaw <T>(existingList, ConvertToLocal(regionBounds, partition)); } } largeObjectTile.GetRaw <T>(existingList); }
public static void Update() { for (int i = 0; i < partitions.Count; i++) { SpatialPartition partition = partitions.Array[i]; partition.Update(); if (partition.NeedsPrune) { ReturnToPool(partition); partition.NeedsPrune = false; } } }
private BehaviorReturnCode initializePathfinder() { Position start = (Position)f_PositionMapper.get(f_ThisEntity); Position finish = (Position)f_PositionMapper.get(f_Target); f_Map = s_EcsInstance.tag_manager.get_entity_by_tag("MAP"); GameMap map = (GameMap)f_GameMapMapper.get(f_Map); f_Camera = s_EcsInstance.tag_manager.get_entity_by_tag("CAMERA"); ViewPort viewport = (ViewPort)f_ViewPortMapper.get(f_Camera); f_Spatial = s_EcsInstance.tag_manager.get_entity_by_tag("SPATIAL"); SpatialPartition spatial = (SpatialPartition)f_SpatialMapper.get(f_Spatial); spatial.QuadTree.setContentAtLocation(f_ThisEntity, start.Pos); s_LastNode = spatial.QuadTree.locateNode(start.Pos); Vector2 sVec, fVec; //s_Center = viewport.getDimensions() / 2; sVec = (start.Pos) / f_TileSize; fVec = (finish.Pos + finish.Offset) / f_TileSize; /* * sVec = (start.Pos + s_Center) / s_TileSize; * fVec = (finish.Pos + s_Center) / s_TileSize; */ s_TargetCell.Position = fVec; s_CurrentCell.Position = sVec; //findPath = new FindPathAction(s_EcsInstance,sVec,fVec, map); APath path = (APath)f_PathMapper.get(f_ThisEntity); path.Start = sVec; path.Finish = fVec; path.Map = map; path.PathState = PathState.Idle; s_TargetCurrentPosition = finish.Pos + s_Offset; //convert to map position s_TargetCurrentPosition = new Vector2((int)s_TargetCurrentPosition.X / f_TileSize, (int)s_TargetCurrentPosition.Y / f_TileSize); s_TargetPreviousPosition = s_TargetCurrentPosition; f_BeginPathingAndMovement = true; return(BehaviorReturnCode.Success); }
public ParticleSystem(ITimeProvider timeProvider, object userData = null, float subdivision = 128.0f) { TimeProvider = timeProvider; Subdivision = subdivision; Particles = new SpatialPartition <ParticleCollection>(Subdivision, (index) => new ParticleCollection(index, Particles.GetSectorBounds(index))); UpdateArgs = new ParticleUpdateArgs(this); RenderArgs = new ParticleRenderArgs(this); var temporaryInstance = Activator.CreateInstance <T>(); temporaryInstance.InitializeSystem(userData, out Updater, out Renderer, out GetPosition, this); }
public static void Initialize(int tileSize, int partitionSize) { largeObjectTile = new PartitionTile(Rectangle.Empty); TileSize = tileSize; PartitionSize = partitionSize; // Initialize pool. for (int i = 0; i < InitialPoolSize; i++) { Rectangle bounds = new Rectangle(0, 0, PartitionSize, PartitionSize); SpatialPartition partition = new SpatialPartition(TileSize, bounds); ReturnToPool(partition); } }
public static void createSpatialPartition(Vector2 ul, Vector2 lr, int tiers) { Entity e = ecs_instance.create(); SpatialPartition spatial = new SpatialPartition(); spatial.QuadTree = new QuadTree <Entity>(ul, lr); spatial.QuadTree.buildQuadTree(tiers); ecs_instance.add_component(e, spatial); ecs_instance.tag_manager.tag_entity("SPATIAL", e); ecs_instance.resolve(e); }
internal static void GetTilesFromRegion(QuickList <PartitionTile> tilesList, Rectangle regionBounds, bool includeLargeObjectTile = true) { for (int i = 0; i < partitions.Count; i++) { SpatialPartition partition = partitions.Array[i]; if (partition.Bounds.Intersects(regionBounds)) { partition.GetTilesFromRegion(tilesList, ConvertToLocal(regionBounds, partition)); } } if (includeLargeObjectTile) { tilesList.Add(largeObjectTile); } }
/// <summary> /// move toward the current cell /// </summary> /// <returns></returns> private BehaviorReturnCode moveTowardsCell() { //get positions, velocity, and heading Position mePos = (Position)s_PositionMapper.get(s_ThisEntity); Velocity meVel = (Velocity)s_VelocityMapper.get(s_ThisEntity); Heading meHeading = (Heading)s_HeadingMapper.get(s_ThisEntity); //get current pos Vector2 pos = mePos.Pos;// +s_Offset; Vector2 vec = new Vector2(s_CurrentCell.Position.X * s_TileSize, s_CurrentCell.Position.Y * s_TileSize); //check for condition that could cause a not-a-number exception //if ((vec - s_Center) == pos) if ((vec) == pos) { return(BehaviorReturnCode.Success); } //create heading from this entityt to targetNode //vec = Vector2.Subtract(vec - s_Center, pos); vec = Vector2.Subtract(vec, pos); vec.Normalize(); //set heading meHeading.setHeading(Vector2.Multiply(vec, meVel.Vel)); //update position pos += meHeading.getHeading(); mePos.Pos = pos; s_moved = true; SpatialPartition spatial = (SpatialPartition)s_SpatialMapper.get(s_Spatial); //remove old reference if (s_LastNode != null) { s_LastNode.Contents.Remove(s_ThisEntity); } //set new position and get new reference spatial.QuadTree.setContentAtLocation(s_ThisEntity, pos); s_LastNode = spatial.QuadTree.locateNode(pos); return(BehaviorReturnCode.Success); }
protected override void process(Entity entity) { Position position = (Position)q_PositionMapper.get(entity); ViewPort camera = (ViewPort)q_ViewPortMapper.get(q_Camera); SpatialPartition spatial = (SpatialPartition)q_SpatialMapper.get(q_Spatial); Vector2 pos = position.Pos + position.Offset; Vector2 origin = camera.getOrigin(); QuadNode <Entity> node = spatial.QuadTree.locateNode(pos); int width = (int)(node.LRCorner.X - node.ULCorner.X); int height = (int)(node.LRCorner.Y - node.ULCorner.Y); Rectangle rec = new Rectangle((int)(node.ULCorner.X - origin.X), (int)(node.ULCorner.Y - origin.Y), width, height); _sprite_batch.Draw(q_Texture, rec, new Color(1f, 0f, 0f, 0f)); }
private static SpatialPartition TakeFromPool(Point position) { // Create new partition if there's none in the pool. if (partitionPool.Count < 1) { return(CreateNewPartition(position, true)); } // Otherwise, return a partition that's in the pool. SpatialPartition partition = partitionPool.Array[partitionPool.Count - 1]; partitions.Add(partition); partitionPool.Remove(partition); partition.UpdatePosition(position); partition.IsActive = true; return(partition); }
public static void Insert(IPartitionObject obj) { if (obj is Component c && !c.Enabled) { return; } if (obj is GameObject go) { InsertGameObject(go); } else { SpatialPartition tile = FetchPartition(obj.PartitionPosition) ?? TakeFromPool(ToPartitionPoint(obj.PartitionPosition)); tile.Insert(obj); } }
private static void InsertGameObject(GameObject go) { if (!go.Enabled || go.IgnoreCulling) { return; } RectangleF bounds = go.Bounds; if (bounds.Width > TileSize || bounds.Height > TileSize) { largeObjectTile.Insert(go); } else { SpatialPartition tile = FetchPartition(go.PartitionPosition) ?? TakeFromPool(ToPartitionPoint(go.PartitionPosition)); tile.Insert(go); } }
protected override void process(Entity entity) { Position position = (Position)p_PositionMapper.get(entity); Velocity velocity = (Velocity)p_VelocityMapper.get(entity); Heading heading = (Heading)p_HeadingMapper.get(entity); Position mPosition = (Position)p_PositionMapper.get(p_Mouse); Transform transform = (Transform)p_TransformMapper.get(entity); Character character = (Character)p_CharacterMapper.get(entity); SpatialPartition spatial = (SpatialPartition)p_SpatialMapper.get(p_Spatial); if (p_FirstRun) { spatial.QuadTree.setContentAtLocation(entity, position.Pos); p_LastNode = spatial.QuadTree.locateNode(position.Pos + position.Offset); p_FirstRun = false; } Vector2 pos = position.Pos; float vel = velocity.Vel; Vector2 head = heading.getHeading(); //reset direction int dirCount = 0; //reset animation //sprite.Column = 0; p_Moved = false; //toggle light? if (InputManager.isKeyToggled(Keys.L)) { Light light = (Light)p_LightMapper.get(p_Mouse); if (light.IsEnabled) { light.IsEnabled = false; } else { light.IsEnabled = true; } } //move up? if (InputManager.isKeyPressed(Keys.W)) { Vector2 dir = new Vector2(0, -1); head += dir; dirCount++; //sprite.Y = MOVE_UP; //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime); p_Moved = true; } //move down? if (InputManager.isKeyPressed(Keys.S)) { Vector2 dir = new Vector2(0, 1); head += dir; dirCount++; //sprite.Y = MOVE_DOWN; //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime); p_Moved = true; } //move left? if (InputManager.isKeyPressed(Keys.A)) { Vector2 dir = new Vector2(-1, 0); head += dir; dirCount++; //sprite.Y = MOVE_LEFT; //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime); p_Moved = true; } //move right? if (InputManager.isKeyPressed(Keys.D)) { Vector2 dir = new Vector2(1, 0); head += dir; dirCount++; //sprite.Y = MOVE_RIGHT; //sprite.X = p_Movement.updateFrame(ecs_instance.ElapsedTime); p_Moved = true; } //move according to the correct speed if (dirCount > 1) { position.Pos = pos + head * vel * (float)Math.Sqrt(2) / 2; } else { position.Pos = pos + head * vel; } /* * Vector2 test = (mPosition.Pos + mPosition.Offset) - pos; * test.Normalize(); * * float angle = VectorHelper.getAngle(new Vector2(1,0), test); * * if (angle >= 0.393f && angle < 1.178f) { sprite.Row = MOVE_UPRIGHT; } * else if (angle >= 1.178f && angle < 1.963f) { sprite.Row = MOVE_UP; } * else if (angle >= 1.963f && angle < 2.749f) { sprite.Row = MOVE_UPLEFT; } * else if (angle >= 2.749f && angle < 3.534f) { sprite.Row = MOVE_LEFT; } * else if (angle >= 3.534f && angle < 4.320f) { sprite.Row = MOVE_DOWNLEFT; } * else if (angle >= 4.320f && angle < 5.105f) { sprite.Row = MOVE_DOWN; } * else if (angle >= 5.105f && angle < 5.890f) { sprite.Row = MOVE_DOWNRIGHT; } * else if (angle >= 5.890f || angle < .393f) { sprite.Row = MOVE_RIGHT; } * * if(p_Moved) * sprite.Column = p_Movement.updateFrame(ecs_instance.ElapsedTime); */ if (p_Moved) { character.CurrentAnimtaion = "MOVING"; } //transform.Rotation = getAngle(pos, mPosition.getPosition()); /* * if (InputManager.isLeftButtonClicked()) * { * EntityFactory ef = new EntityFactory(ecs_instance); * * Vector2 dir = mPosition.getPosition() + mPosition.Offset - new Vector2(16) - pos; * * dir.Normalize(); * * Transform trans = new Transform(); * trans.Rotation = -VectorHelper.getAngle(new Vector2(1, 0), dir); * trans.RotationOrigin = new Vector2(16); * * ef.createCollidingProjectile(pos + dir * 16, dir, 10f, 1000, ef.createLight(true, 35, new Vector3(pos + position.Offset, 10), 0.7f, Color.Purple.ToVector4()), trans, entity); * * UtilFactory uf = new UtilFactory(ecs_instance); * uf.createSound("audio\\effects\\fire", true,0.5f); * }*/ p_LastFired += ecs_instance.ElapsedTime; if (InputManager.isLeftButtonDown() && (p_LastFired >= 3 * p_FireRate)) { Target target = (Target)p_TargetMapper.get(p_Target); if (target.Active) { p_LastFired = 0; Position targetPos = (Position)p_PositionMapper.get(p_Target); Vector2 dir = targetPos.Pos + targetPos.Offset - new Vector2(16) - pos; dir.Normalize(); Transform trans = new Transform(); trans.Rotation = -VectorHelper.getAngle(new Vector2(1, 0), dir); trans.RotationOrigin = new Vector2(0, 16); UtilFactory.createMeleeAction(pos + dir * 16, dir, trans, entity); } } if (InputManager.isRightButtonDown() && (p_LastFired >= p_FireRate)) { Target target = (Target)p_TargetMapper.get(p_Target); if (target.Active) { p_LastFired = 0; Position targetPos = (Position)p_PositionMapper.get(p_Target); Vector2 dir = targetPos.Pos + targetPos.Offset - new Vector2(16) - pos; //Vector2 dir = mPosition.Pos + mPosition.Offset - new Vector2(16) - pos;// +new Vector2(-20 + (float)rand.NextDouble() * 40, -20 + (float)rand.NextDouble() * 40); dir = VectorHelper.rotateVectorRadians(dir, -0.08726f + (float)rand.NextDouble() * 0.1745f); dir.Normalize(); Transform trans = new Transform(); trans.Rotation = -VectorHelper.getAngle(new Vector2(1, 0), dir); trans.RotationOrigin = new Vector2(16); EntityFactory.createCollidingProjectile(pos + dir * 16, dir, 10f, 1000, EntityFactory.createLight(true, 2, new Vector3(pos + position.Offset, 10), 0.7f, Color.OrangeRed.ToVector4()), trans, entity); UtilFactory.createSound("audio\\effects\\fire", true, 0.5f); } } if (InputManager.isKeyToggled(Keys.B)) { if (!p_StatWindowOpen) { p_StatWindow = UIFactory.createStatWindow(entity, new Point(100, 100), new Point(300, 315), 20); p_StatWindowOpen = true; } else { ecs_instance.delete_entity(p_StatWindow); p_StatWindowOpen = false; } } if (InputManager.isKeyToggled(Keys.I)) { if (!p_InvWindowOpen) { p_InvWindow = UIFactory.createInventoryWindow(entity, new Point(300, 100), new Point(300, 300), 20, 10, 10); p_InvWindowOpen = true; } else { ecs_instance.delete_entity(p_InvWindow); p_InvWindowOpen = false; } } if (InputManager.isKeyToggled(Keys.R)) { List <Entity> locals = spatial.QuadTree.findAllWithinRange(pos, 300); if (locals.Count > 1) { Target target = (Target)p_TargetMapper.get(p_Target); Sprite sprite = (Sprite)p_SpriteMapper.get(p_Target); sprite.Visible = true; target.Active = true; Entity closest = null; float min = float.MaxValue; for (int i = 0; i < locals.Count; i++) { if (locals[i] == entity) { continue; } Position p = (Position)p_PositionMapper.get(locals[i]); if (p == null) { continue; } float dist = Vector2.Distance(p.Pos, position.Pos); if (dist < min) { closest = locals[i]; min = dist; } } target.TargetEntity = closest; } } if (!p_Moved) { p_Movement.reset(); character.CurrentAnimtaion = "IDLE"; } else { if (p_LastNode != null) { p_LastNode.Contents.Remove(entity); } p_LastNode = spatial.QuadTree.setContentAtLocation(entity, pos + new Vector2(16, 16)); } //TEST FUNCTIONS PAST HERE if (InputManager.isKeyPressed(Keys.Up)) { transform.Rotation += 0.1f; } if (InputManager.isKeyPressed(Keys.Down)) { transform.Rotation -= 0.1f; } if (InputManager.isKeyPressed(Keys.Left)) { transform.RotationOrigin = new Vector2(16, 32); } if (InputManager.isKeyPressed(Keys.Right)) { transform.RotationOrigin = new Vector2(0); } if (InputManager.isKeyPressed(Keys.P)) { NPCFactory ef = new NPCFactory(ecs_instance); ef.createFollower(mPosition.Pos + mPosition.Offset - new Vector2(16), entity, rand.Next(50, 300)); } if (InputManager.isKeyToggled(Keys.O)) { NPCFactory ef = new NPCFactory(ecs_instance); //ef.createBatEnemy(mPosition.Pos + mPosition.Offset - new Vector2(16),15); CharacterDef cDef = GameConfig.CharacterDefs["BAT"]; cDef.SkillLevel = 15; ef.createCharacter(cDef, mPosition.Pos + mPosition.Offset - new Vector2(16)); } if (InputManager.isKeyToggled(Keys.U)) { ActionDef def = GameConfig.ActionDefs["TEST_DMG"]; ActionFactory.createAction(def, entity, entity); } }
private static Point ConvertToLocal(Point worldPoint, SpatialPartition localPartition) => new Point(worldPoint.X - localPartition.Bounds.X, worldPoint.Y - localPartition.Bounds.Y);
private static Rectangle ConvertToLocal(Rectangle worldBounds, SpatialPartition localPartition) => new Rectangle(worldBounds.X - localPartition.Bounds.X, worldBounds.Y - localPartition.Bounds.Y, worldBounds.Width, worldBounds.Height);
protected override void process(Entity entity) { Projectile projectile = (Projectile)p_ProjectileMapper.get(entity); projectile.ElapsedTime += ecs_instance.ElapsedTime; //is it time for the projectile to die? if (projectile.ElapsedTime >= projectile.LifeTime) { ecs_instance.delete_entity(entity); return; } Position position = (Position)p_PositionMapper.get(entity); Velocity velocity = (Velocity)p_VelocityMapper.get(entity); Heading heading = (Heading)p_HeadingMapper.get(entity); SpatialPartition spatial = (SpatialPartition)p_SpatialMapper.get(p_Spatial); Vector2 pos = position.Pos; //List<Entity> locals = spatial.QuadTree.retrieveContentsAtLocation(pos); List <Entity> locals = spatial.QuadTree.findAllWithinRange(pos, 32); //anything retrieved? if (locals != null) { //anyone aruond? if (locals.Count > 0) { //for all the locals see if we should do anything for (int i = 0; i < locals.Count; i++) { //dont interact with whom fired you if (locals[i] == projectile.Originator) { continue; } Life life = (Life)p_LifeMapper.get(locals[i]); //if no life, uh, don't check for it... if (life == null) { continue; } //if target is dead, dont worry if (!life.IsAlive) { continue; } //is there an interaction available? Interactable interaction = (Interactable)p_InteractionMapper.get(locals[i]); if (interaction != null) { //get this local's position Position localPosition = (Position)p_PositionMapper.get(locals[i]); //are we close to it? //23 - minimal radial distance for collision to occur if (Vector2.Distance(pos + position.Offset, localPosition.Pos + localPosition.Offset) < 23) { //can we do anything to it? if (interaction.SupportedInteractions.PROJECTILE_COLLIDABLE && interaction.SupportedInteractions.ATTACKABLE) { Factions lfactions = (Factions)p_FactionMapper.get(locals[i]); Factions pfactions = (Factions)p_FactionMapper.get(projectile.Originator); if (lfactions.OwnerFaction.FactionType == pfactions.OwnerFaction.FactionType) { continue; } //UtilFactory.createAttack(projectile.Originator, locals[i], AttackType.Projectile); ActionDef def = GameConfig.ActionDefs["RANGED_DMG"]; ActionFactory.createAction(def, projectile.Originator, locals[i]); //destory yourself ecs_instance.delete_entity(entity); return; } } } } } } MapCollidable mapCollide = (MapCollidable)p_MapCollidableMapper.get(entity); if (mapCollide != null) { if (mapCollide.Collided) { /* * Vector2 norm = mapCollide.ResponseVector; * norm.Normalize(); * Vector2 reflect = Vector2.Reflect(heading.getHeading(), norm); * reflect.Normalize(); * * //Transform trans = (Transform)p_TransformMapper.get(entity); * * //trans.Rotation = -VectorHelper.getAngle2(new Vector2(1,0), reflect); * * heading.setHeading(reflect); */ UtilFactory.createSound("audio\\effects\\hitwall", true, 0.5f); ecs_instance.delete_entity(entity); } } pos += heading.getHeading() * velocity.Vel; position.Pos = pos; }
/// <summary> /// checks for nearby enemy factions /// </summary> /// <returns>true if hostile was detected</returns> private bool hasDetectedHostile() { if (w_LastNode == null) { return(false); } SpatialPartition spatial = (SpatialPartition)w_SpatialMapper.get(w_Spatial); Position position = (Position)w_PositionMapper.get(w_ThisEntity); List <Entity> locals = spatial.QuadTree.findAllWithinRange(position.Pos, 100f); //nothing to detect if (locals.Count == 0) { return(false); } for (int i = 0; i < locals.Count; i++) { //dont look at yourself if (locals[i] == w_ThisEntity) { continue; } Factions factions = (Factions)w_FactionMapper.get(locals[i]); if (factions == null) { continue; } //is this local known to this entity if (factions.KnownFactions.ContainsKey(w_EntityFaction.OwnerFaction.Name)) { //should this entity be hostile towards this local? if (factions.KnownFactions[w_EntityFaction.OwnerFaction.Name].Value < 0) { Position pos = (Position)w_PositionMapper.get(w_ThisEntity); Position tPos = (Position)w_PositionMapper.get(locals[i]); if (Vector2.Distance(pos.Pos + pos.Offset, tPos.Pos + tPos.Offset) <= 200f) { //go hostile against it w_Target = locals[i]; Aggrivation aggro = (Aggrivation)w_AggroMapper.get(w_ThisEntity); aggro.Target = w_Target; return(true); } else { continue; } } } } return(false); }
protected override void process(Entity entity) { MeleeAction action = (MeleeAction)m_MeleeActionMapper.get(entity); Position position = (Position)m_PositionMapper.get(entity); SpatialPartition spatial = (SpatialPartition)m_SpatialMapper.get(m_Spatial); action.ElapsedTime += ecs_instance.ElapsedTime; //is it time for the melee action to die? if (action.ElapsedTime >= action.Lifetime) { ecs_instance.delete_entity(entity); return; } //retrieve all local entities //List<Entity> locals = spatial.QuadTree.retrieveContentsAtLocation(position.Pos); List <Entity> locals = spatial.QuadTree.findAllWithinRange(position.Pos, action.Range); //is the location good? if (locals != null) { //is there anyone here? if (locals.Count > 0) { for (int i = 0; i < locals.Count; i++) { //dont attempt to melee owner if (locals[i] == action.Owner) { continue; } if (action.HitByAction.Contains(locals[i])) { continue; } Life life = (Life)m_LifeMapper.get(locals[i]); //if no life, dont bother if (life == null) { continue; } //if not alive, dont bother if (!life.IsAlive) { continue; } //interaction available? Interactable interactions = (Interactable)m_InteractionMapper.get(locals[i]); if (interactions != null) { Position lPosition = (Position)m_PositionMapper.get(locals[i]); Position oPosition = (Position)m_PositionMapper.get(action.Owner); Vector2 lToO = (oPosition.Pos + oPosition.Offset) - (lPosition.Pos + lPosition.Offset); //local to owner Heading head = (Heading)m_HeadingMapper.get(entity); //get the weapon heading bool facing = (Vector2.Dot(head.getHeading(), lToO) < 0); //is the weapon facing the local? //if you're facing, are you within range? if (facing && (Vector2.Distance(lPosition.Pos + lPosition.Offset, position.Pos + position.Offset) <= action.Range)) { //does it support this interaction? if (interactions.SupportedInteractions.MELEE_ACTIONABLE && interactions.SupportedInteractions.ATTACKABLE) { Factions lfactions = (Factions)m_FactionMapper.get(locals[i]); Factions pfactions = (Factions)m_FactionMapper.get(action.Owner); //dont attack allies if (lfactions.OwnerFaction.FactionType == pfactions.OwnerFaction.FactionType) { continue; } //add to hit-list so we dont attack it again on swing follow-through action.HitByAction.Add(locals[i]); //create melee attack UtilFactory.createAttack(action.Owner, locals[i], AttackType.Melee); //destroy melee action //ecs_instance.delete_entity(entity); //return; } } } } } } //get info for rotation update Heading heading = (Heading)m_HeadingMapper.get(entity); Transform transform = (Transform)m_TransformMapper.get(entity); //rotate melee by degrees over the melee arc float rot = (((float)action.Animation.updateFrame(ecs_instance.ElapsedTime) / (float)action.Animation.Frames) * action.ArcDegrees) - (action.ArcDegrees / 2f); transform.Rotation = rot * (((float)Math.PI) / 180f) - VectorHelper.getAngle(new Vector2(1, 0), heading.getHeading()); //adjust the arc based on current position (i.e., move with the player) Position ownerPos = (Position)m_PositionMapper.get(action.Owner); Vector2 pos = ownerPos.Pos + new Vector2(16, 0);// +ownerPos.getOffset(); Vector2 dir = heading.getHeading(); dir.Normalize(); position.Pos = pos + dir * 10; }