// Try attacking another actor public int TryAttackingAnotherActor(Actor target,Attack attack) { int result = 0; Random rand = new Random(); // Try to hit against ac int toHit = attack.toHit; int hit = toHit+rand.Next(0, 20); // If hit successful if(hit >= target.ac) { // Get what damage should be done int dmgMod = 0; int dmgRaw = dmgMod + rand.Next(attack.dmgMin, attack.dmgMax); int dmgFinal = dmgRaw; // Do damage to the target target.hp -= dmgFinal; // Desc. the target's state string targetState = target.genderNomTitle+" "; string s = "appears to be in good health"; float hpp = (target.hp / target.hpMax); if(hpp > 0) { s = "appears close to death."; } if (hpp > 25) { s = "appears gravely wounded."; } if (hpp > 50) { s = "appears somewhat wounded."; } if (hpp > 75) { s = "appears slightly wounded."; } targetState += s; // If the target dies if (target.hp <= 0) { target.UpdateStatus(); // Log if (isPlayer) { ui.Log("You " + attack.verb1P + " the " + target.name + ", killing it.", Color4.Yellow); } else { if (target == worldMap.player) { ui.Log("The " + name + " " + attack.verb3P + " you. You die!", Color4.Red); } else { ui.Log("The " + name + " " + attack.verb3P + " the "+target.name+", killing it."); } } result = 3; } else { // Log if (isPlayer) { ui.Log("You " + attack.verb1P + " the " + target.name + ". "+ targetState, Color4.Yellow); } else { if (target == worldMap.player) { ui.Log("The " + name + " " + attack.verb3P + " you.", Color4.Red); } else { ui.Log("The " + name + " " + attack.verb3P + " the " + target.name + ". " + targetState); } } result = 2; } } else { // If attack misses // Log if (isPlayer) { ui.Log("You try to " + attack.verb1P + " the " + target.name + ", but miss."); } else { if (target == worldMap.player) { ui.Log("The " + name + " tries to " + attack.verb1P + " you, but misses."); } else { ui.Log("The " + name + " tries to " + attack.verb1P + " the " + target.name + ", but misses."); } } result = 1; } return result; }
// Run public int Run() { int result = 0; // Whether a meaningful action has been taken // If asleep if (actor.isAsleep) { actor.actionPoints = 0; } else { // If is hostile if(actor.isHostile) { // If has target if(targetEnemy != null) { // If the target isn't dead and can be seen if(!targetEnemy.dead && targetEnemy.visible && worldMap.TileDistance(actor.tileX, actor.tileY, targetEnemy.tileX, targetEnemy.tileY) <= actor.sightRange) { // If in melee range to target if (worldMap.TileDistance(actor.tileX,actor.tileY, targetEnemy.tileX, targetEnemy.tileY) <= 1) { // If can attack melee if (typeAttack == AI_TYPE_ATTACK_MELEE) { // Try to attack if (actor.TryAttackingAnotherActor(targetEnemy, actor.attackMain) > 0) { actor.actionPoints -= 6; } } } else { // Get path to target Path path = new Path(); path = worldMap.FindPathToTile(actor.tileX, actor.tileY, targetEnemy.tileX, targetEnemy.tileY); int tx = 0; int ty = 0; if (path.length > 1) { if (path.nodes[1].x > actor.tileX) { tx = 1; } if (path.nodes[1].x < actor.tileX) { tx = -1; } if (path.nodes[1].y > actor.tileY) { ty = 1; } if (path.nodes[1].y < actor.tileY) { ty = -1; } } // Try moving towards target if (tx != 0 || ty != 0) { // If successful if (actor.TryMoving(tx, ty) > 0) { actor.actionPoints -= 3; result = 1; Console.WriteLine(actor.nameTitle+" moves to ("+actor.tileX+","+actor.tileY+")"); } else { actor.actionPoints = 0; } } else { actor.actionPoints = 0; } } } else { targetEnemy = null; actor.actionPoints = 0; } } else { // Find an enemy worldMap.FindTargetInSight(actor, TARGET_TYPE_ENEMY); actor.actionPoints = 0; } } else { actor.actionPoints = 0; } } return result; }
// Find target public int FindTargetInSight(Actor actor, int type) { int result = 0; // Draw lines of sight int tx = 0; int ty = 0; double sx = 0; double sy = 0; // For every direction for (int d = 0; d < 360; d++) { // If a target hasn't been found yet if (result == 0) { sx = Math.Cos(d); sy = Math.Sin(d); // Reveal distance based on perception skill for (int l = 1; l <= actor.sightRange; l++) { tx = (int)Math.Round(sx * l); ty = (int)Math.Round(sy * l); if (actor.tileX + tx >= 0 && actor.tileX + tx < mapSizeX && actor.tileY + ty >= 0 && actor.tileY + ty < mapSizeY) { // Check for walls if (tilesData[actor.tileX + tx, actor.tileY + ty, mapLevelCurrent].type == WorldMap.TILE_TYPE_WALL) { break; } // Check for doors if (tilesData[actor.tileX + tx, actor.tileY + ty, actor.tileZ].type == WorldMap.TILE_TYPE_DOOR) { if (!tilesDoors[actor.tileX + tx, actor.tileY + ty].open) { break; } } // If type is an enemy if (type == ActorAI.TARGET_TYPE_ENEMY) { // If the player is at the sight tile if (player.tileX == actor.tileX + tx && player.tileY == actor.tileY + ty && player.tileZ == actor.tileZ) { // If the player is an enemy if(!player.dead && player.faction != actor.faction) { actor.ai.targetEnemy = player; result = 1; break; } } else { Actor a = tilesActors[actor.tileX + tx, actor.tileY + ty]; if (a != null) { // If an actor is at the sight position if (a.tileX == actor.tileX + tx && a.tileY == actor.tileY + ty && a.tileZ == actor.tileZ) { // If the actor is an enemy if (!a.dead && a.faction != actor.faction) { actor.ai.targetEnemy = a; result = 1; break; } } } } } } } } else { break; } tx = 0; ty = 0; } return result; }