private void BlipMove(ref MonsterCharacter.InputFrame frame) { frame.up = dir.y; frame.right = dir.x; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dir.y, dir.x) * Mathf.Rad2Deg); if (blipTimer > 0) { blipTimer -= Time.deltaTime; return; } blipTimer = BlipTime; dir = Vec2I.zero; if (Random.value < BlipWaitChance) { return; } if (Leashed) { if ((homePosition - transform.position).sqrMagnitude >= LeashRange * LeashRange) { Vector2 distance = transform.position - Camera.main.transform.position; if (Mathf.Max(distance.x) > Options.AlertDistance.x || Mathf.Max(distance.y) > Options.AlertDistance.y) { Destroy(gameObject); } } } if (Random.value < BlipRandomChance) { dir = Vec2I.directions[Random.Range(1, Vec2I.directions.Length)]; return; } if (HuntPlayer) { if (LastKnownPlayerRoom != -1) { targetRoom = LastKnownPlayerRoom; } } if (targetRoom >= 0 && targetRoom < Room.Rooms.Length) { //simplistic behavior //dir = Room.Rooms[targetRoom].parent[thing.gridPos.x, thing.gridPos.y] - thing.gridPos; //return; //to avoid monsters piling up on single point if (Vec2I.Manhattan(Room.Rooms[targetRoom].gridPos, thing.gridPos) < NearSteps) { return; } if (!AI.RoomPath(thing.gridPos, Room.Rooms[targetRoom], MaxSteps, out Vec2I[] path))
private void FillInputFrame(ref MonsterCharacter.InputFrame frame) { if (Input.GetKeyDown(KeyCode.R)) { destinationRoom = Random.Range(0, Room.Rooms.Length); Debug.Log("Moving towards room \"" + Room.Rooms[destinationRoom].gameObject.name + "\""); } /*int currentRoom = Room.GetRoomIndex(character.thingController.gridPos); * * if (currentRoom == destinationRoom) * return;*/ frame.up = dir.y; frame.right = dir.x; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dir.y, dir.x) * Mathf.Rad2Deg); if (timer > 0f) { return; } timer = DecisionTime; dir = Vec2I.zero; /*if (currentRoom == -1 || destinationRoom == -1) * return; * int nextRoom = Room.Rooms[currentRoom].ClosestNeighborTowards[destinationRoom]; * if (nextRoom == -1) * return; * * Vec2I p = Vec2I.illegalMin; * * Vec2I p = Room.Parents[nextRoom][thing.gridPos.x, thing.gridPos.y]; * * HeatmapNode h = Heatmap.GetNode(p); * if (h != null) * { * int closest = Room.Distance[nextRoom][thing.gridPos.x, thing.gridPos.y]; * * foreach (HeatmapNode n in h.neighbors) * { * int distance = Room.Distance[nextRoom][n.gridPos.x, n.gridPos.y]; * if (distance < closest) * { * p = n.gridPos; * closest = distance; * } * } * } * * if (p != Vec2I.illegalMin) * dir = p - thing.gridPos;*/ }
private void OnInputRequest(ref MonsterCharacter.InputFrame frame) { if (target == null) return; if (dualSwingTimer > 0f) dualSwingTimer -= Time.deltaTime; frame.LocalTransform = true; int steps = Vec2I.Max(thing.gridPos, target.thingController.gridPos); if (steps <= MaxAttackConsiderationStepCount) { frame.WantDirection = TowardsTarget; if (character.CurrentWeapon.IsReady && character.CurrentOffhand.IsReady) { if (Random.value > .5f) frame.PrimaryAttackContinuous = true; else frame.SecondaryAttackContinuous = true; dualSwingTimer = DualSwingDelay; } else if (dualSwingTimer <= 0f) { frame.PrimaryAttackContinuous = true; frame.SecondaryAttackContinuous = true; } frame.up = 1f; return; } if (CanSeeTargetGrid) { frame.WantDirection = TowardsTarget; if (steps > StopMovingStepCount) frame.up = 1f; return; } Vec2I smart = SmartMove; if (SmartMove != Vec2I.zero) { frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(smart.y, smart.x) * Mathf.Rad2Deg); if (steps > StopMovingStepCount) frame.up = 1; } }
private void StandAround(ref MonsterCharacter.InputFrame frame) { if (lookatTarget != null) { Vector2 dif = lookatTarget.transform.position - transform.position; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dif.y, dif.x) * Mathf.Rad2Deg); } if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); lookatTarget = null; //look at player Vector2 distance = transform.position - Camera.main.transform.position; if (Mathf.Max(distance.x) > Options.AlertDistance.x || Mathf.Max(distance.y) > Options.AlertDistance.y) { return; } Collider2D[] hits = Physics2D.OverlapAreaAll( (Vector2)transform.position + Options.AlertDistance, (Vector2)transform.position - Options.AlertDistance, LayerMask.Walkers); foreach (Collider2D hit in hits) { MonsterCharacter monster = hit.GetComponent <MonsterCharacter>(); if (monster == null) { continue; } if (monster.GetComponent <PlayerControls>() != null) { lookatTarget = monster; } } }
private void StandAround(ref MonsterCharacter.InputFrame frame) { if (target != null) { character.OnInputRequest = Hesitate; return; } Vec2I dif = playerGridPos - thing.gridPos; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dif.y, dif.x) * Mathf.Rad2Deg); if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); if (activated) { if (Vec2I.Manhattan(playerGridPos, thing.gridPos) <= PlayerDistance.x) { character.OnInputRequest = MoveOut; return; } if (targetRoom >= 0 || targetRoom < Room.Rooms.Length) { Room room = Room.Rooms[targetRoom]; if (TheGrid.Valid(playerGridPos) && TheGrid.Valid(thing.gridPos)) { if (room.steps[playerGridPos.x, playerGridPos.y] < room.steps[thing.gridPos.x, thing.gridPos.y]) { character.OnInputRequest = MoveOut; return; } } } } }
private void MoveOut(ref MonsterCharacter.InputFrame frame) { Vector2 dif = TheGrid.WorldPosition(moveTarget) - (Vector2)transform.position; if (dif != Vector2.zero) { dir = dif.normalized; } frame.up = dir.y; frame.right = dir.x; if (LookAtMoveDir) { lookDir = dir; } frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg); if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); LookAtMoveDir = Random.value < LookAtMoveDirChance; if (targetRoom < 0 || targetRoom >= Room.Rooms.Length) { return; } Room room = Room.Rooms[targetRoom]; if (!AI.RoomPath(thing.gridPos, room, MaxSteps, out Vec2I[] path))
private void FillInputFrame(ref MonsterCharacter.InputFrame frame) { frame.up = dir.y; frame.right = dir.x; frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(dir.y, dir.x) * Mathf.Rad2Deg); if (timer > 0f) { return; } timer = DecisionTime; dir = Vector2.zero; Mouse.UpdateWorldPosition(); if (Mouse.InWorld) { if (Mouse.GridPosition != lastMouseGrid) { Vec2I a = thing.gridPos; Vec2I b = Mouse.GridPosition; if (AI.GetPath(a, b, Vec2I.Max(a, b), out Vec2I[] path))
private void Hesitate(ref MonsterCharacter.InputFrame frame) { if (target == null) { return; } if (character.CurrentWeapon != null && character.CurrentWeapon.IsReady && Random.value < AggroChance && OnScreen && RayToTarget(character.transform.position)) //RayToTarget(character.CurrentWeapon.AttackRayStartPosition)) //fails on boss and other multi weapon monsters, also the weapon barrel might be inside wall { character.OnInputRequest = Attack; attackTimer = AttackTime; attacked = false; secondaryAttacked = false; return; } if (decisionTimer > 0f) { if (LookAtTargetOverride) { frame.WantDirection = TowardsTarget; } decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); LookAtTargetOverride = Random.value < LookAtPlayerChance; if (Random.value < IdleChance) { MovementDecision = Vector2.zero; DirectionDecision = character.LookDirection; character.OnInputRequest = Move; return; } if (Random.value < RandomMoveChance) { float a = Random.value * Mathf.PI * 2f; MovementDecision.x = Mathf.Cos(a); MovementDecision.y = Mathf.Sin(a); DirectionDecision = character.LookDirection; character.OnInputRequest = Move; return; } if ((MovementDecision = (Vector2)SmartMove) != Vector2.zero) { MovementDecision.Normalize(); DirectionDecision = Quaternion.Euler(0, 0, AxMath.SafeAtan2(MovementDecision.y, MovementDecision.x) * Mathf.Rad2Deg); character.OnInputRequest = Move; } }
private void MoveOut(ref MonsterCharacter.InputFrame frame) { if (target != null) { character.OnInputRequest = Hesitate; return; } if (PlayerTooFar) { character.OnInputRequest = StandAround; } if (moveTarget != Vec2I.illegalMin) { Vector2 dif = TheGrid.WorldPosition(moveTarget) - (Vector2)transform.position; if (dif != Vector2.zero) { dir = dif.normalized; } frame.up = dir.y; frame.right = dir.x; if (LookAtMoveDir) { lookDir = dir; } frame.WantDirection = Quaternion.Euler(0, 0, AxMath.SafeAtan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg); } if (decisionTimer > 0f) { decisionTimer -= Time.deltaTime; return; } decisionTimer = Random.Range(DecisionInterval.x, DecisionInterval.y); LookAtMoveDir = Random.value < LookAtMoveDirChance; if (targetRoom < 0 || targetRoom >= Room.Rooms.Length) { return; } Room room = Room.Rooms[targetRoom]; if (Vec2I.Max(room.gridPos, thing.gridPos) < 3) { if (MissionObjective == 0) { Messaging.GUI.CommsMessage.Invoke(0, OnExitMessagePortrait, OnExitMessage); MissionObjective++; Messaging.Mission.MissionStatus.Invoke(true); } Instantiate(TeleportEffect, transform.position, Quaternion.identity, LevelLoader.TemporaryObjects); Destroy(gameObject); } if (!AI.RoomPath(thing.gridPos, room, MaxSteps, out Vec2I[] path))
public Quaternion TowardsPosition(Vector3 position) { Vector2 dif = (position - transform.position); return(Quaternion.Euler(0, 0, AxMath.SafeAtan2(dif.y, dif.x) * Mathf.Rad2Deg)); }