void reactionComputingThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (!e.Cancelled)
{
// Don't let multiple threads eat atoms. Nor let two check for two reactions at
// the same time with an overlapping atom.
lock (CoreModel.Instance)
{
IList<Tile> tilesInReaction = e.Result as IList<Tile>;
// Final check if someone ate our atoms in-between and unbalanced us.
if (tilesInReaction != null && tilesInReaction.Count > 0 && tilesInReaction.Sum(t => t.Atom.IonCharge) == 0)
{
// Add points. Not displayed outside of Avalanche and Trickle, oh well.
model.Points += tilesInReaction.Sum(t => t.Atom.Points);
this.updateAtomsLeftOrPointsCounter();
StringBuilder equation = new StringBuilder();
tilesInReaction = tilesInReaction.OrderBy(tile => tile, this._orderTilesByAtomNameComparer).ToList();
String previousElement = tilesInReaction[0].Atom.Element;
String currentElement = "";
int quantity = 0;
Tile finalTile = tilesInReaction[tilesInReaction.Count - 1];
// Equations only on non-Avalanche and non-Trickle mode.
foreach (Tile reactionTile in tilesInReaction)
{
// For some reason, these appear at high levels in large chains.
// HACK: don't display it.
if (reactionTile.IsEmpty())
{
continue;
}
reactionTile.AtomSprite.ColorOperation = ColorOperation.Add;
reactionTile.AtomSprite.RedRate = 3f;
reactionTile.AtomSprite.GreenRate = 3f;
reactionTile.AtomSprite.BlueRate = 3f;
this._reactingTiles.Add(reactionTile);
// Print out something nice, like 2Fl + H + Li.
// Or, in Avalanche/Trickle, 1 + 16 + 9.
if (model.CurrentLevel != CoreModel.AVALANCHE_LEVEL && model.CurrentLevel != CoreModel.TRICKLE_LEVEL)
{
currentElement = reactionTile.Atom.Element;
if (previousElement == currentElement)
{
quantity++;
}
else if (previousElement != currentElement)
{
// Print nothing if quantity = 1, i.e. we like to
// see "H + Cl" not "1H + 1Cl"
equation.Append(string.Format("{0}{1} + ", (quantity > 1 ? quantity.ToString() : ""), previousElement));
// 1, not 0, because we won't do this elsewhere; fixes bug where
// Fl-Fl-H-H becomes 2Fl + H.
quantity = 1;
}
previousElement = reactionTile.Atom.Element;
}
else
{
equation.Append(string.Format("{0} + ", reactionTile.Atom.Points));
}
reactionTile.Empty(); // Prevent quick clickers from chaining
}
// Dump of last element
if (model.CurrentLevel != CoreModel.AVALANCHE_LEVEL && model.CurrentLevel != CoreModel.TRICKLE_LEVEL)
{
equation.Append(string.Format("{0}{1} + ", (quantity > 1 ? quantity.ToString() : ""), previousElement));
}
if (equation.Length >= 3)
{
// Trickle mode bug?
equation.Remove(equation.Length - 3, 3); // trailing " + "
}
TowerText equationText = new TowerText(this.AddText(equation.ToString()));
equationText.YVelocity = 15;
equationText.AlphaRate = -0.1f;
equationText.Scale = 24;
equationText.AddShadow();
equationText.InsertNewLines(SpriteManager.Camera.Width);
AudioManager.Instance.PlaySound(CoreModel.SOUND_FILE_PATH + "reaction.mp3");
this._reactionText.Add(equationText.BaseText);
this._reactionText.Add(equationText.EffectText);
}
if (model.CurrentLevel >= CoreModel.FIRST_PUZZLE_LEVEL &&
model.CurrentLevel <= CoreModel.LAST_PUZZLE_LEVEL &&
model.NextAtom == Atom.NONE &&
!model.IsLevelOver())
{
// Puzzle mode, out of atoms; game over.
model.SignalGameOver();
}
}
}
}