public override void Update(float deltaTime, uint tick) { //Run through our system logic here //Note, we do this for every entity for (int i = 0; i < _targetComponentArray.Length; i++) { //First, we need to make sure we're dealing with an active entity if (!_entityManager.IsEntityActive(i)) { return; } if (!_targetComponentArray[i].IsActive) { //This entity does not have a target. Let's fix that //Lets assess potential targets //For now, this means looping through entities by team id and picking one that isn't our team _potentialTargetList.Clear(); for (int t = 0; t < _teamComponentArray.Length; t++) { //Skip ourselves ;) && Skip any entity that isn't active if (t != i && _entityManager.IsEntityActive(t) && _teamComponentArray[i] != _teamComponentArray[t]) { _potentialTargetList.Add(t); } } //Now we should ideally have a magical list of potential targets. Let's pick one from that list if (_potentialTargetList.Count > 0) { int targetIndex = _randomSystem.GetNext(0, _potentialTargetList.Count - 1); ref TargetComponent targetComponent = ref _entityManager.AddComponentToEntity <TargetComponent>(i); targetComponent.TargetId = _potentialTargetList[targetIndex]; targetComponent.TargetAcquiredTick = tick; _logger.Log(string.Format("Entity {0} found target Entity {1}. Acquired at tick {2}", i, _potentialTargetList[targetIndex], tick)); } } }
public override void Update(float deltaTime, uint tick) { //Loop through all entities that have a target component for (int i = 0; i < _targetComponentArray.Length; i++) { //First, we need to make sure we're dealing with an active entity if (!_entityManager.IsEntityActive(i)) { return; } //Now we need to make sure this current entity "i" has a target. If not, then this system isn't interested if (_targetComponentArray[i].IsActive) { //Make sure the target has a position component if (_positionComponentArray[_targetComponentArray[i].TargetId].IsActive) { //This entity has a target, now we need to see if we're outside of attack range float dist = _positionComponentArray[i].Position.DistanceTo(_positionComponentArray[_targetComponentArray[i].TargetId].Position); if (dist > _combatStatsComponents[i].AttackRange) { //Well, our worst fears have come true, the target is out of range... Guess we need to get on the dusty trail //First we need to check to see if we were previously pathing, and if so, should we be pathing to the same point if (!_targetComponentArray[i].TargetPosition.SameAs(_positionComponentArray[_targetComponentArray[i].TargetId].Position) || _pathToTargetComponent[i].Path == null) { //Well, they're not in the same position, so we should probably update that //TODO, we should be pathing to somewhere "near" the target based on some range information about this entity. This could easily be offloaded to a pathfinding manager. _pathToTargetComponent[i].Path = _pathfindingManager.GetPath(_positionComponentArray[i], _positionComponentArray[_targetComponentArray[i].TargetId]); _pathToTargetComponent[i].CurrentPathSegmentIndex = 0; //Since we're setting a path to where the target currently is, we need to rememer where the target currently is _targetComponentArray[i].TargetPosition.Set(_positionComponentArray[_targetComponentArray[i].TargetId].Position); _logger.Log(string.Format("Updated path for Entity {0} to Target {1} X:{2} Y:{3} Z:{4}", i, _targetComponentArray[i].TargetId, _positionComponentArray[_targetComponentArray[i].TargetId].Position.X, _positionComponentArray[_targetComponentArray[i].TargetId].Position.Y, _positionComponentArray[_targetComponentArray[i].TargetId].Position.Z)); _pathToTargetComponent[i].IsActive = true; } } } } } }
public override void Update(float deltaTime, uint tick) { for (int i = 0; i < _pathToPositionComponentArray.Length; i++) { //C'mon. If the dude isn't active you shouldn't do a damn thing. Get out of herer if (!_entityManager.IsEntityActive(i)) { return; } //Now that we know this is an active Entity, does it even have a path? if (_pathToPositionComponentArray[i].IsActive) { //There's a path. Now, what to do? //This function should use the entities move speed to move them along the path. //It should move along the path segment by segment. //Move the motherf*@!cker //Grab a short hand name for this array element, other wise the following code would be waaaaay longer PathToPositionComponent ptpc = _pathToPositionComponentArray[i]; //Get this doods move speed float moveSpeed = _combatStatsComponents[i].MovementSpeed; //Grab ye olde vector from this entity to the target position Vector3D moveDeltaVector = ptpc.Path[ptpc.CurrentPathSegmentIndex] - _positionComponentArray[i].Position; //Normalize the vector, then scale it according to the move speed moveDeltaVector.Normalize(); //This is cool. This normalized vector is our direction, so just go ahead and record that _positionComponentArray[i].Direction = moveDeltaVector; moveDeltaVector.Scale(moveSpeed * deltaTime); //Now add the delta vector to our position _positionComponentArray[i].Position.Add(moveDeltaVector); _logger.Log(string.Format("Entity {0} moved to {1}, {2}, {3}", i, _positionComponentArray[i].Position.X, _positionComponentArray[i].Position.Y, _positionComponentArray[i].Position.Z)); //We should check to see if we're at the end point of a path segment OR we've moved beyond our target point //First, get the distance float dist = _positionComponentArray[i].Position.DistanceTo(ptpc.Path[ptpc.CurrentPathSegmentIndex]); //Now get the dot product to know if we're beyond our target point Vector3D postMoveVector = ptpc.Path[ptpc.CurrentPathSegmentIndex] - _positionComponentArray[i].Position; float dotProd = Vector3D.DotProduct(postMoveVector, _positionComponentArray[i].Direction); //Now, we can compare this squared distance to our squared epsilon. This saves us from having to perform a square root calculation if (dist <= _combatStatsComponents[i].AttackRange || dotProd <= 0.0f) { //We can now consider ourselves "arrived" at this point //Set the current position to this point, and then up the current path index. We also need to check to see if this was the last path segment //and if so, consider our travel along this path as complete. _positionComponentArray[i].Position.Set(ptpc.Path[ptpc.CurrentPathSegmentIndex]); if (ptpc.CurrentPathSegmentIndex == ptpc.Path.Length - 1) { //Oh boy, we're at the end. What a treat. //Lets remove the path component, because that's within our power _pathToPositionComponentArray[i].Path = null; _pathToPositionComponentArray[i].IsActive = false; _logger.Log(string.Format("Entity {0} arrived at end of path!", i)); } else { //Not the end mf. Press on. //Update our index to the next segment... and that's cool. ptpc.CurrentPathSegmentIndex++; } } } } }