public static ObjectAction DestroyWhenHpIsZeroAndMaybeDropPowerUp( long chanceToDropPowerUpInMilliPercent, // ranges from 0 (meaning 0%) to 100,000 (meaning 100%) Dictionary <string, DTDanmakuImage> spriteNameToImageDictionary, Dictionary <string, EnemyObjectTemplate> enemyObjectTemplates, Dictionary <string, DTDanmakuSound> soundNameToSoundDictionary, GuidGenerator guidGenerator) { string soundEffectName = guidGenerator.NextGuid(); BooleanExpression isHpZero = BooleanExpression.LessThanOrEqualTo( MathExpression.MilliHP(), MathExpression.Constant(0)); ObjectAction playEnemyDeathSoundEffectAction = ObjectAction.PlaySoundEffect(soundEffectName: soundEffectName); soundNameToSoundDictionary.Add(soundEffectName, DTDanmakuSound.EnemyDeath); DestructionAnimationGenerator.GenerateDestructionAnimationResult generateDestructionAnimationResult = DestructionAnimationGenerator.GenerateDestructionAnimation( orderedSprites: new List <DTDanmakuImage> { DTDanmakuImage.Explosion1, DTDanmakuImage.Explosion2, DTDanmakuImage.Explosion3, DTDanmakuImage.Explosion4, DTDanmakuImage.Explosion5, DTDanmakuImage.Explosion6, DTDanmakuImage.Explosion7, DTDanmakuImage.Explosion8, DTDanmakuImage.Explosion9 }, millisecondsPerSprite: 20, guidGenerator: guidGenerator); foreach (var entry in generateDestructionAnimationResult.spriteNameToImageDictionary) { spriteNameToImageDictionary.Add(entry.Key, entry.Value); } foreach (var entry in generateDestructionAnimationResult.enemyObjectTemplates) { enemyObjectTemplates.Add(entry.Key, entry.Value); } ObjectAction possiblySpawnPowerUpAction = ObjectAction.Condition( condition: BooleanExpression.LessThan( MathExpression.RandomInteger(MathExpression.Constant(100 * 1000)), MathExpression.Constant(chanceToDropPowerUpInMilliPercent)), action: ObjectAction.SpawnPowerUp()); return(ObjectAction.Condition( condition: isHpZero, action: ObjectAction.Union( playEnemyDeathSoundEffectAction, generateDestructionAnimationResult.objectAction, possiblySpawnPowerUpAction, ObjectAction.Destroy()))); }