/* Copyright (c) 2008-2010, developers of the Ascension Log Visualizer
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package com.googlecode.logVisualizer.logData.logSummary;
import java.util.Collection;
import com.googlecode.logVisualizer.logData.Item;
import com.googlecode.logVisualizer.logData.turn.TurnInterval;
/**
* This immutable class calculates and holds all the data on various quest
* turncounts.
*/
public final class QuestTurncounts {
private final int mosquitoQuestTurns;
private final int templeOpeningTurns;
private final int tavernQuestTurns;
private final int batQuestTurns;
private final int knobQuestTurns;
private final int friarsQuestTurns;
private final int cyrptQuestTurns;
private final int trapzorQuestTurns;
private final int chasmQuestTurns;
private final int airshipQuestTurns;
private final int castleQuestTurns;
private final int ballroomOpeningTurns;
private final int pirateQuestTurns;
private final int blackForrestQuestTurns;
private final int desertOasisQuestTurns;
private final int spookyravenQuestTurns;
private final int templeCityQuestTurns;
private final int palindomeQuestTurns;
private final int pyramidQuestTurns;
private final int warIslandOpeningTurns;
private final int warIslandQuestTurns;
private final int dodQuestTurns;
/**
* Constructs a new instance and calculates all quest turncounts.
*
* @param turns
* The turn rundown of the ascension.
* @param droppedItems
* All dropped items during the ascension.
*/
public QuestTurncounts(final Collection<TurnInterval> turns,
final Collection<Item> droppedItems) {
if (turns == null) {
throw new NullPointerException("Turn rundown set must not be null.");
}
if (droppedItems == null) {
throw new NullPointerException(
"Dropped items list must not be null.");
}
this.mosquitoQuestTurns = QuestTurncounts.getTurnsUntilItemFound("Spooky Forest",
"mosquito larva", turns, droppedItems);
this.templeOpeningTurns = QuestTurncounts.calculateTempleOpening(turns,
droppedItems);
this.tavernQuestTurns = QuestTurncounts.getTurnsInLocation("Typical Tavern Quest",
turns);
this.batQuestTurns = QuestTurncounts.getTurnsUntilOtherLocationOpen(
"Guano Junction", "Boss Bat's Lair", turns)
+ QuestTurncounts.getTurnsInLocation("Boss Bat's Lair", turns);
this.knobQuestTurns = QuestTurncounts.getTurnsUntilItemFound(
"Outskirts of The Knob", "Knob Goblin encryption key", turns,
droppedItems)
+ QuestTurncounts.getTurnsInLocation("Knob Goblin Harem", turns)
+ QuestTurncounts.getTurnsInLocation("King's Chamber", turns);
this.friarsQuestTurns = QuestTurncounts.getTurnsUntilItemFound(
"Dark Neck of the Woods", "dodecagram", turns, droppedItems)
+ QuestTurncounts.getTurnsUntilItemFound("Dark Heart of the Woods",
"box of birthday candles", turns, droppedItems)
+ QuestTurncounts.getTurnsUntilItemFound("Dark Elbow of the Woods",
"eldritch butterknife", turns, droppedItems);
this.cyrptQuestTurns = QuestTurncounts.getTurnsInLocation("Defiled Cranny", turns)
+ QuestTurncounts.getTurnsInLocation("Defiled Nook", turns)
+ QuestTurncounts.getTurnsInLocation("Defiled Alcove", turns)
+ QuestTurncounts.getTurnsInLocation("Defiled Niche", turns)
+ QuestTurncounts.getTurnsInLocation("Haert of the Cyrpt", turns);
this.trapzorQuestTurns = QuestTurncounts.getTurnsInLocation("Itznotyerzitz Mine",
turns)
+ QuestTurncounts.getTurnsInLocation("Mining (In Disguise)", turns)
+ QuestTurncounts.getTurnsInLocation("Goatlet", turns);
this.chasmQuestTurns = QuestTurncounts.getTurnsInLocation("Orc Chasm", turns);
this.airshipQuestTurns = QuestTurncounts.getTurnsUntilItemFound("Fantasy Airship",
"S.O.C.K.", turns, droppedItems);
this.castleQuestTurns = QuestTurncounts.getTurnsUntilOtherLocationOpen(
"Giant's Castle", "Hole in the Sky", turns);
this.ballroomOpeningTurns = QuestTurncounts.getTurnsUntilOtherLocationOpen(
"Haunted Pantry", "Haunted Billiards Room", turns)
+ QuestTurncounts.getTurnsUntilOtherLocationOpen("Haunted Billiards Room",
"Haunted Library", turns)
+ QuestTurncounts.getTurnsUntilOtherLocationOpen("Haunted Library",
"Haunted Bedroom", turns)
+ QuestTurncounts.getTurnsUntilOtherLocationOpen("Haunted Bedroom",
"Haunted Ballroom", turns);
this.pirateQuestTurns = QuestTurncounts.getTurnsUntilOtherLocationOpen(
"Pirate Cove", "Barrrney's Barrr", turns)
+ QuestTurncounts.getTurnsUntilOtherLocationOpen("Barrrney's Barrr",
"F'c'le", turns)
+ QuestTurncounts.getTurnsInLocation("Cap'm Caronch's Map", turns)
+ QuestTurncounts.getTurnsInLocation("The Infiltrationist", turns)
+ QuestTurncounts.getTurnsUntilOtherLocationOpen("F'c'le", "Poop Deck",
turns)
+ QuestTurncounts.getTurnsUntilOtherLocationOpen("Poop Deck",
"Belowdecks", turns)
+ QuestTurncounts.getTurnsUntilOtherLocationOpen("Belowdecks",
"Palindome", turns);
this.blackForrestQuestTurns = QuestTurncounts.getTurnsInLocation("Black Forest",
turns);
this.desertOasisQuestTurns = QuestTurncounts.getTurnsInLocation(
"Desert (Unhydrated)", turns)
+ QuestTurncounts.getTurnsInLocation("Desert (Ultrahydrated)", turns)
+ QuestTurncounts.getTurnsInLocation("Oasis in the Desert", turns);
this.spookyravenQuestTurns = QuestTurncounts.getTurnsAfterLocationOpen(
"Haunted Ballroom", "Black Forest", turns)
+ QuestTurncounts.getTurnsInLocation("Haunted Wine Cellar (Northwest)",
turns)
+ QuestTurncounts.getTurnsInLocation("Haunted Wine Cellar (Northeast)",
turns)
+ QuestTurncounts.getTurnsInLocation("Haunted Wine Cellar (Southwest)",
turns)
+ QuestTurncounts.getTurnsInLocation("Haunted Wine Cellar (Southeast)",
turns)
+ QuestTurncounts.getTurnsInLocation("Haunted Wine Cellar", turns)
+ QuestTurncounts.getTurnsInLocation("Lord Spookyraven", turns)
+ QuestTurncounts.getTurnsInLocation("Summoning Chamber", turns);
this.templeCityQuestTurns = QuestTurncounts.getTurnsInLocation("Hidden Temple",
turns)
+ QuestTurncounts.getTurnsInLocation("Hidden City", turns)
+ QuestTurncounts.getTurnsInLocation("Hidden City (Altar)", turns)
+ QuestTurncounts.getTurnsInLocation("Hidden City (Temple)", turns);
this.palindomeQuestTurns = QuestTurncounts.getTurnsInLocation("Palindome", turns)
+ QuestTurncounts.getTurnsAfterLocationOpen("Knob Goblin Laboratory",
"Palindome", turns)
+ QuestTurncounts.getTurnsAfterLocationOpen("Whitey's Grove", "Palindome",
turns);
this.pyramidQuestTurns = QuestTurncounts.getTurnsInLocation("The Upper Chamber",
turns)
+ QuestTurncounts.getTurnsInLocation("The Middle Chamber", turns)
+ QuestTurncounts.getTurnsInLocation("The Lower Chamber", turns)
+ QuestTurncounts.getTurnsInLocation("The Lower Chambers (Token/Empty)",
turns)
+ QuestTurncounts.getTurnsInLocation("The Lower Chambers (Rubble/Bomb)",
turns)
+ QuestTurncounts.getTurnsInLocation(
"The Lower Chambers (Empty/Empty/Ed's Chamber)", turns)
+ QuestTurncounts.getTurnsInLocation("The Lower Chambers (Empty/Rubble)",
turns)
+ QuestTurncounts.getTurnsInLocation("Ed the Undying", turns);
this.warIslandOpeningTurns = QuestTurncounts.getTurnsAfterLocationOpen(
"Hippy Camp", "Palindome", turns)
+ QuestTurncounts.getTurnsInLocation(
"Wartime Hippy Camp (Hippy Disguise)", turns)
+ QuestTurncounts.getTurnsInLocation("Wartime Hippy Camp (Frat Disguise)",
turns)
+ QuestTurncounts.getTurnsAfterLocationOpen("Frat House", "Palindome",
turns)
+ QuestTurncounts.getTurnsInLocation(
"Wartime Frat House (Hippy Disguise)", turns)
+ QuestTurncounts.getTurnsInLocation("Wartime Frat House (Frat Disguise)",
turns);
this.warIslandQuestTurns = QuestTurncounts.getTurnsInLocation("Hatching Chamber",
turns)
+ QuestTurncounts.getTurnsInLocation("Feeding Chamber", turns)
+ QuestTurncounts.getTurnsInLocation("Guards' Chamber", turns)
+ QuestTurncounts.getTurnsInLocation("Queen's Chamber", turns)
+ QuestTurncounts.getTurnsInLocation(
"Barrel with Something Burning in it", turns)
+ QuestTurncounts.getTurnsInLocation("Over Where the Old Tires Are", turns)
+ QuestTurncounts.getTurnsInLocation("Near an Abandoned Refrigerator",
turns)
+ QuestTurncounts.getTurnsInLocation("Out by that Rusted-Out Car", turns)
+ QuestTurncounts.getTurnsInLocation("Wartime Sonofa Beach", turns)
+ QuestTurncounts.getTurnsInLocation("Themthar Hills", turns)
+ QuestTurncounts.getTurnsInLocation("Barn", turns)
+ QuestTurncounts.getTurnsInLocation("Family Plot", turns)
+ QuestTurncounts.getTurnsInLocation("Pond", turns)
+ QuestTurncounts.getTurnsInLocation("Other Back 40", turns)
+ QuestTurncounts.getTurnsInLocation("Back 40", turns)
+ QuestTurncounts.getTurnsInLocation("Granary", turns)
+ QuestTurncounts.getTurnsInLocation("Bog", turns)
+ QuestTurncounts.getTurnsInLocation("Shady Thicket", turns)
+ QuestTurncounts.getTurnsInLocation("Battlefield (Frat Uniform)", turns)
+ QuestTurncounts.getTurnsInLocation("Battlefield (Hippy Uniform)", turns)
+ QuestTurncounts.getTurnsInLocation("Big Wisniewski", turns)
+ QuestTurncounts.getTurnsInLocation("The Big Wisniewski", turns)
+ QuestTurncounts.getTurnsInLocation("The Man", turns);
this.dodQuestTurns = QuestTurncounts
.getTurnsInLocation("Greater-Than Sign", turns)
+ QuestTurncounts.getTurnsUntilItemFound("Dungeons of Doom", "dead mimic",
turns, droppedItems);
}
/**
* @param turns
* The turn rundown of the ascension.
* @param droppedItems
* All dropped items during the ascension.
* @return Turns spent.
*/
private static int calculateTempleOpening(final Collection<TurnInterval> turns,
final Collection<Item> droppedItems) {
final int spookyGro = QuestTurncounts.getTurnsUntilItemFound("Spooky Forest",
"Spooky-Gro fertilizer", turns, droppedItems);
final int sapling = QuestTurncounts.getTurnsUntilItemFound("Spooky Forest",
"spooky sapling", turns, droppedItems);
return spookyGro > sapling ? spookyGro : sapling;
}
/**
* @param areaName
* The name of the area the turns are spent in.
* @param turns
* The turn rundown of the ascension.
* @return Turns spent.
*/
private static int getTurnsInLocation(final String areaName,
final Collection<TurnInterval> turns) {
int turnsSpent = 0;
for (final TurnInterval ti : turns) {
if (ti.getAreaName().equals(areaName)) {
turnsSpent += ti.getTotalTurns();
}
}
return turnsSpent;
}
/**
* @param areaName
* The name of the area the turns are spent in.
* @param openedLocation
* The name of the area whose opening stops the turncounting.
* @param turns
* The turn rundown of the ascension.
* @return Turns spent.
*/
private static int getTurnsUntilOtherLocationOpen(final String areaName,
final String openedLocation, final Collection<TurnInterval> turns) {
int turnsSpent = 0;
int firstTurnInOpenedLocation = Integer.MAX_VALUE;
for (final TurnInterval ti : turns) {
if (ti.getAreaName().equals(openedLocation)) {
firstTurnInOpenedLocation = ti.getStartTurn();
break;
}
}
for (final TurnInterval ti : turns) {
if (ti.getStartTurn() >= firstTurnInOpenedLocation) {
break;
} else if (ti.getAreaName().equals(areaName)) {
turnsSpent += ti.getTotalTurns();
}
}
return turnsSpent;
}
/**
* @param areaName
* The name of the area the turns are spent in.
* @param alreadyOpenLocation
* The name of the area which has to be already open before the
* turncounting starts.
* @param turns
* The turn rundown of the ascension.
* @return Turns spent.
*/
private static int getTurnsAfterLocationOpen(final String areaName,
final String alreadyOpenLocation,
final Collection<TurnInterval> turns) {
return QuestTurncounts.getTurnsAfterLocationOpenUntilOtherLocationOpen(areaName,
alreadyOpenLocation, "", turns);
}
/**
* @param areaName
* The name of the area the turns are spent in.
* @param alreadyOpenLocation
* The name of the area which has to be already open before the
* turncounting starts.
* @param toBeOpenedLocation
* The name of the area whose opening stops the turncounting.
* @param turns
* The turn rundown of the ascension.
* @return Turns spent.
*/
private static int getTurnsAfterLocationOpenUntilOtherLocationOpen(
final String areaName, final String alreadyOpenLocation,
final String toBeOpenedLocation,
final Collection<TurnInterval> turns) {
int turnsSpent = 0;
int firstTurnInAlreadyOpenedLocation = Integer.MIN_VALUE;
int firstTurnInToBeOpenedLocation = Integer.MAX_VALUE;
for (final TurnInterval ti : turns) {
if ((firstTurnInAlreadyOpenedLocation == Integer.MIN_VALUE)
&& ti.getAreaName().equals(alreadyOpenLocation)) {
firstTurnInAlreadyOpenedLocation = ti.getStartTurn();
} else if (ti.getAreaName().equals(toBeOpenedLocation)) {
firstTurnInToBeOpenedLocation = ti.getStartTurn();
break;
}
}
for (final TurnInterval ti : turns) {
if (ti.getStartTurn() >= firstTurnInAlreadyOpenedLocation) {
if (ti.getStartTurn() >= firstTurnInToBeOpenedLocation) {
break;
} else if (ti.getAreaName().equals(areaName)) {
turnsSpent += ti.getTotalTurns();
}
}
}
return turnsSpent;
}
/**
* @param areaName
* The name of the area the turns are spent in.
* @param itemName
* The name of the item which has to be found.
* @param turns
* The turn rundown of the ascension.
* @param droppedItems
* All dropped items during the ascension.
* @return Turns spent.
*/
private static int getTurnsUntilItemFound(final String areaName,
final String itemName, final Collection<TurnInterval> turns,
final Collection<Item> droppedItems) {
int turnsSpent = 0;
int finishedOnTurn = Integer.MAX_VALUE;
for (final Item i : droppedItems) {
if (i.getName().equals(itemName)) {
finishedOnTurn = i.getFoundOnTurn();
break;
}
}
for (final TurnInterval ti : turns) {
if (ti.getAreaName().equals(areaName)) {
if ((ti.getStartTurn() <= finishedOnTurn)
&& (ti.getEndTurn() <= finishedOnTurn)) {
turnsSpent += ti.getTotalTurns();
} else if ((ti.getStartTurn() <= finishedOnTurn)
&& (ti.getEndTurn() > finishedOnTurn)) {
turnsSpent += finishedOnTurn - ti.getStartTurn();
break;
}
}
}
return turnsSpent;
}
/**
* @return The amount of turns the Mosquito quest took.
*/
public int getMosquitoQuestTurns() {
return this.mosquitoQuestTurns;
}
/**
* @return The amount of turns opening the Hidden Temple took.
*/
public int getTempleOpeningTurns() {
return this.templeOpeningTurns;
}
/**
* @return The amount of turns the Tavern quest took.
*/
public int getTavernQuestTurns() {
return this.tavernQuestTurns;
}
/**
* @return The amount of turns the Bat quest took.
*/
public int getBatQuestTurns() {
return this.batQuestTurns;
}
/**
* @return The amount of turns the Knob Goblin quest took.
*/
public int getKnobQuestTurns() {
return this.knobQuestTurns;
}
/**
* @return The amount of turns the Friars quest took.
*/
public int getFriarsQuestTurns() {
return this.friarsQuestTurns;
}
/**
* @return The amount of turns the Cyrpt quest took.
*/
public int getCyrptQuestTurns() {
return this.cyrptQuestTurns;
}
/**
* @return The amount of turns the Trapzor quest took.
*/
public int getTrapzorQuestTurns() {
return this.trapzorQuestTurns;
}
/**
* @return The amount of turns the Orc Chasm quest took.
*/
public int getChasmQuestTurns() {
return this.chasmQuestTurns;
}
/**
* @return The amount of turns the Airship quest took.
*/
public int getAirshipQuestTurns() {
return this.airshipQuestTurns;
}
/**
* @return The amount of turns the Castle quest took.
*/
public int getCastleQuestTurns() {
return this.castleQuestTurns;
}
/**
* @return The amount of turns opening the ballroom took.
*/
public int getBallroomOpeningTurns() {
return this.ballroomOpeningTurns;
}
/**
* @return The amount of turns the Pirate quest took.
*/
public int getPirateQuestTurns() {
return this.pirateQuestTurns;
}
/**
* @return The amount of turns the Black Forest quest took.
*/
public int getBlackForrestQuestTurns() {
return this.blackForrestQuestTurns;
}
/**
* @return The amount of turns finding the pyramid took.
*/
public int getDesertOasisQuestTurns() {
return this.desertOasisQuestTurns;
}
/**
* @return The amount of turns the Spookyraven quest took.
*/
public int getSpookyravenQuestTurns() {
return this.spookyravenQuestTurns;
}
/**
* @return The amount of turns the Hidden City quest took.
*/
public int getTempleCityQuestTurns() {
return this.templeCityQuestTurns;
}
/**
* @return The amount of turns the Palindome quest took.
*/
public int getPalindomeQuestTurns() {
return this.palindomeQuestTurns;
}
/**
* @return The amount of turns completing the pyramid took.
*/
public int getPyramidQuestTurns() {
return this.pyramidQuestTurns;
}
/**
* @return The amount of turns opening the battlefield took.
*/
public int getWarIslandOpeningTurns() {
return this.warIslandOpeningTurns;
}
/**
* @return The amount of turns completing the battlefield with all
* sidequests took.
*/
public int getWarIslandQuestTurns() {
return this.warIslandQuestTurns;
}
/**
* @return The amount of turns the DoD quest took.
*/
public int getDodQuestTurns() {
return this.dodQuestTurns;
}
}