Пример #1
0
 public Player targetClosestPC(Creature crt)
 {
     Player pc = null;
     int farDist = 99;
     foreach (Player p in mod.playerList)
     {
         if ((!p.charStatus.Equals("Dead")) && (p.hp >= 0) && (!p.steathModeOn))
         {
             int dist = CalcDistance(crt.combatLocX, crt.combatLocY, p.combatLocX, p.combatLocY);
             if (dist == farDist)
             {
                 //since at same distance, do a random check to see if switch or stay with current PC target
                 if (gv.sf.RandInt(20) > 10)
                 {
                     //switch target
                     pc = p;
                     if (gv.mod.debugMode)
                     {
                         gv.cc.addLogText("<font color='yellow'>target:" + pc.name + "</font><BR>");
                     }
                 }
             }
             else if (dist < farDist)
             {
                 farDist = dist;
                 pc = p;
                 if (gv.mod.debugMode)
                 {
                     gv.cc.addLogText("<font color='yellow'>target:" + pc.name + "</font><BR>");
                 }
             }
         }
     }
     return pc;
 }
Пример #2
0
        public Coordinate targetBestPointLocation(Creature crt)
        {
            Coordinate targetLoc = new Coordinate(-1,-1);
            //JamesManhattan Utility maximization function for the VERY INTELLIGENT CREATURE CASTER
            int utility = 0; //utility
            int optimalUtil = 0; //optimal utility, a storage of the highest achieved
            Coordinate selectedPoint = new Coordinate(crt.combatLocX, crt.combatLocY); //Initial Select Point is Creature itself, then loop through all squares within range!
            for (int y = gv.sf.SpellToCast.range; y > -gv.sf.SpellToCast.range; y--)  //start at far range and work backwards does a pretty good job of avoiding hitting allies.
            {
                for (int x = gv.sf.SpellToCast.range; x > -gv.sf.SpellToCast.range; x--)
                {
                    utility = 0; //reset utility for each point tested
                    selectedPoint = new Coordinate(crt.combatLocX + x, crt.combatLocY + y);

                    //check if selected point is a valid location on combat map
                    if ((selectedPoint.X < 0) || (selectedPoint.X > 6) || (selectedPoint.Y < 0) || (selectedPoint.Y > 6))
                    {
                        continue;
                    }

                    //check if selected point is in LoS, if not skip this point
                    int endX = selectedPoint.X * gv.squareSize + (gv.squareSize / 2);
                    int endY = selectedPoint.Y * gv.squareSize + (gv.squareSize / 2);
                    int startX = crt.combatLocX * gv.squareSize + (gv.squareSize / 2);
                    int startY = crt.combatLocY * gv.squareSize + (gv.squareSize / 2);
                    if (!isVisibleLineOfSight(new Coordinate(endX, endY), new Coordinate(startX, startY)))
                    {
                        continue;
                    }

                    if (selectedPoint == new Coordinate(crt.combatLocX, crt.combatLocY))
                    {
                        utility -= 4; //the creature at least attempts to avoid hurting itself, but if surrounded might fireball itself!
                        if (crt.hp <= crt.hpMax / 4) //caster is wounded, definately avoids itself.
                        {
                            utility -= 4;
                        }
                    }
                    foreach (Creature crtr in mod.currentEncounter.encounterCreatureList) //if its allies are in the burst subtract a point, or half depending on how evil it is.
                    {
                        if (this.CalcDistance(crtr.combatLocX, crtr.combatLocY, selectedPoint.X, selectedPoint.Y) <= gv.sf.SpellToCast.aoeRadius) //if friendly creatures are in the AOE burst, count how many, subtract 0.5 for each, evil is evil
                        {
                            utility -= 1;
                        }
                    }
                    foreach (Player tgt_pc in mod.playerList)
                    {
                        if ((this.CalcDistance(tgt_pc.combatLocX, tgt_pc.combatLocY, selectedPoint.X, selectedPoint.Y) <= gv.sf.SpellToCast.aoeRadius) && (tgt_pc.hp > 0)) //if players are in the AOE burst, count how many, total count is utility  //&& sf.GetLocalInt(tgt_pc.Tag, "StealthModeOn") != 1  <-throws an annoying message if not found!!
                        {
                            utility += 2;
                            if (utility > optimalUtil)
                            {
                                //optimal found, choose this point
                                optimalUtil = utility;
                                targetLoc = selectedPoint;
                            }
                        }
                    }
                    if (gv.mod.debugMode)
                    {
                        gv.cc.addLogText("<font color='yellow'>(" + selectedPoint.X + "," + selectedPoint.Y + "):" + utility + "</font><BR>");
                    }
                }
            }

            return targetLoc;
        }
Пример #3
0
        public void TargetCast(Player pc)
        {
            int endX = targetHighlightCenterLocation.X * gv.squareSize + (gv.squareSize / 2);
            int endY = targetHighlightCenterLocation.Y * gv.squareSize + (gv.squareSize / 2);
            int startX = pc.combatLocX * gv.squareSize + (gv.squareSize / 2);
            int startY = pc.combatLocY * gv.squareSize + (gv.squareSize / 2);

            if ((isValidCastTarget(pc)) && (isVisibleLineOfSight(new Coordinate(endX, endY), new Coordinate(startX, startY))))
            {
                if ((targetHighlightCenterLocation.X < pc.combatLocX) && (!pc.combatFacingLeft)) //attack left
                {
                    pc.token = gv.cc.flip(pc.token);
                    pc.combatFacingLeft = true;
                }
                else if ((targetHighlightCenterLocation.X > pc.combatLocX) && (pc.combatFacingLeft)) //attack right
                {
                    pc.token = gv.cc.flip(pc.token);
                    pc.combatFacingLeft = false;
                }
                //doCombatCast(pc);
                gv.touchEnabled = false;
                creatureToAnimate = null;
                playerToAnimate = pc;
                gv.Invalidate();
                animationState = AnimationState.PcCastAttackAnimation;
                gv.postDelayed("doAnimation", 5 * mod.combatAnimationSpeed);
            }
        }
Пример #4
0
        public void doOnHitScriptBasedOnFilename(string filename, Creature crt, Player pc)
        {
            if (!filename.Equals("none"))
            {
                try
                {
                    if (filename.Equals("onHitBeetleFire.cs"))
                    {
                        float resist = (float)(1f - ((float)pc.damageTypeResistanceTotalFire / 100f));
                        float damage = (1 * gv.sf.RandInt(2)) + 0;
                        int fireDam = (int)(damage * resist);

                        if (gv.mod.debugMode)
                        {
                            addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        addLogText("<font color='aqua'>" +	pc.name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" +	fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        pc.hp -= fireDam;
                    }
                    else if (filename.Equals("onHitOneFire.cs"))
                    {
                        float resist = (float)(1f - ((float)crt.damageTypeResistanceValueFire / 100f));
                        float damage = 1.0f;
                        int fireDam = (int)(damage * resist);

                        if (gv.mod.debugMode)
                        {
                            addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        addLogText("<font color='aqua'>" +	crt.cr_name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" +	fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        crt.hp -= fireDam;
                    }
                    else if (filename.Equals("onHitOneTwoFire.cs"))
                    {
                        float resist = (float)(1f - ((float)crt.damageTypeResistanceValueFire / 100f));
                        float damage = (1 * gv.sf.RandInt(2)) + 0;
                        int fireDam = (int)(damage * resist);

                        if (gv.mod.debugMode)
                        {
                            addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        addLogText("<font color='aqua'>" +	crt.cr_name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" +	fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        crt.hp -= fireDam;
                    }
                    else if (filename.Equals("onHitTwoThreeFire.cs"))
                    {
                        float resist = (float)(1f - ((float)crt.damageTypeResistanceValueFire / 100f));
                        float damage = (1 * gv.sf.RandInt(2)) + 1;
                        int fireDam = (int)(damage * resist);

                        if (gv.mod.debugMode)
                        {
                            addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        addLogText("<font color='aqua'>" +	crt.cr_name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" +	fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        crt.hp -= fireDam;
                    }
                    else if (filename.Equals("onHitPcPoisonedLight.cs"))
                    {
                        int saveChkRoll = gv.sf.RandInt(20);
                        int saveChk = saveChkRoll + pc.reflex;
                        int DC = 13;
                        if (saveChk >= DC) //passed save check
                        {
                            addLogText("<font color='yellow'>" + pc.name + " avoids being poisoned" + "</font>" +
                                    "<BR>");
                            if (gv.mod.debugMode)
                            {
                                addLogText("<font color='yellow'>" + saveChkRoll + " + " + pc.reflex + " >= " + DC + "</font>" +
                                            "<BR>");
                            }
                        }
                        else //failed check
                        {
                            addLogText("<font color='red'>" + pc.name + " is poisoned" + "</font>" + "<BR>");
                            Effect ef = gv.mod.getEffectByTag("poisonedLight");
                            pc.AddEffectByObject(ef, gv.mod.WorldTime);
                        }
                    }
                    else if (filename.Equals("onHitPcPoisonedMedium.cs"))
                    {
                        int saveChkRoll = gv.sf.RandInt(20);
                        int saveChk = saveChkRoll + pc.reflex;
                        int DC = 16;
                        if (saveChk >= DC) //passed save check
                        {
                            addLogText("<font color='yellow'>" + pc.name + " avoids being poisoned" + "</font>" +
                                    "<BR>");
                            if (gv.mod.debugMode)
                            {
                                addLogText("<font color='yellow'>" + saveChkRoll + " + " + pc.reflex + " >= " + DC + "</font>" +
                                            "<BR>");
                            }
                        }
                        else //failed check
                        {
                            addLogText("<font color='red'>" + pc.name + " is poisoned" + "</font>" + "<BR>");
                            Effect ef = gv.mod.getEffectByTag("poisonedMedium");
                            pc.AddEffectByObject(ef, gv.mod.WorldTime);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //IBMessageBox.Show(game, "failed to run script");
                }
            }
        }
Пример #5
0
 public void BasicAttacker(Creature crt)
 {
     Player pc = targetClosestPC(crt);
     gv.sf.CombatTarget = pc;
     gv.sf.ActionToTake = "Attack";
 }
Пример #6
0
        public int doActualCombatAttack(Player pc, Creature crt, int attackNumber)
        {
            //always decrement ammo by one whether a hit or miss
            this.decrementAmmo(pc);

            int attackRoll = gv.sf.RandInt(20);
            int attackMod = CalcPcAttackModifier(pc);
            int attack = attackRoll + attackMod;
            int defense = CalcCreatureDefense(crt);
            int damage = CalcPcDamageToCreature(pc, crt);
            //natural 20 always hits
            if ((attack >= defense) || (attackRoll == 20)) //HIT
            {
                crt.hp = crt.hp - damage;
                gv.cc.addLogText("<font color='aqua'>" + pc.name + "</font>" +
                        "<font color='white'>" + " attacks " + "</font>" +
                        "<font color='silver'>" + crt.cr_name + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + " and HITS (" + "</font>" +
                        "<font color='lime'>" + damage + "</font>" +
                        "<font color='white'>" + " damage)" + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + attackRoll + " + " + attackMod + " >= " + defense + "</font>" +
                        "<BR>");

                //#region onScoringHit script of creature
                doOnHitScriptBasedOnFilename(mod.getItemByResRefForInfo(pc.MainHandRefs.resref).onScoringHit, crt, pc);
                //#endregion
                Item it = mod.getItemByResRefForInfo(pc.AmmoRefs.resref);
                if (it != null)
                {
                    doOnHitScriptBasedOnFilename(mod.getItemByResRefForInfo(pc.AmmoRefs.resref).onScoringHit, crt, pc);
                }

                //play attack sound for melee (not ranged)
                if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).category.Equals("Melee"))
                {
                    gv.PlaySound(mod.getItemByResRefForInfo(pc.MainHandRefs.resref).itemOnUseSound);
                }

                //Draw floaty text showing damage above PC

                int txtH = (int)gv.drawFontReg.Height;
                int shiftUp = 0 - (attackNumber * txtH);
                floatyTextOn = true;
                gv.cc.addFloatyText(new Coordinate(crt.combatLocX, crt.combatLocY), damage + "", shiftUp);
                gv.postDelayed("doFloatyText", 100);

                if (crt.hp <= 0)
                {
                    gv.cc.addLogText("<font color='lime'>You killed the " + crt.cr_name + "</font><BR>");
                    try
                    {
                        for (int x = mod.currentEncounter.encounterCreatureList.Count - 1; x >= 0; x--)
                        {
                            if (mod.currentEncounter.encounterCreatureList[x] == crt)
                            {
                                try
                                {
                                    //do OnDeath LOGIC TREE
                                    gv.cc.doLogicTreeBasedOnTag(crt.onDeathLogicTree, crt.onDeathParms);
                                    mod.currentEncounter.encounterCreatureList.RemoveAt(x);
                                    mod.currentEncounter.encounterCreatureRefsList.RemoveAt(x);
                                }
                                catch (Exception e)
                                {
                                    //e.printStackTrace();
                                }
                            }
                        }
                        //mod.currentEncounter.encounterCreatureList.remove(crt);
                    }
                    catch (Exception e)
                    {
                        //e.printStackTrace();
                    }
                    return 2; //killed
                }
                else
                {
                    return 1; //hit
                }
            }
            else //MISSED
            {
                //play attack sound for melee (not ranged)
                if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).category.Equals("Melee"))
                {
                    gv.PlaySound(mod.getItemByResRefForInfo(pc.MainHandRefs.resref).itemOnUseSound);
                }
                gv.cc.addLogText("<font color='aqua'>" + pc.name + "</font>" +
                        "<font color='white'>" + " attacks " + "</font>" +
                        "<font color='gray'>" + crt.cr_name + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + " and MISSES" + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + attackRoll + " + " + attackMod + " < " + defense + "</font>" +
                        "<BR>");
                return 0; //missed
            }
        }
Пример #7
0
 public void doAnimationController()
 {
     if (animationState == AnimationState.None)
     {
         return;
     }
     else if (animationState == AnimationState.PcMeleeAttackAnimation)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         Player pc = mod.playerList[currentPlayerIndex];
         doCombatAttack(pc);
     }
     else if (animationState == AnimationState.CreatureHitAnimation)
     {
         drawHitAnimation = false;
         hitAnimationLocation = new Coordinate();
         gv.Invalidate();
         //check for end of encounter
         checkEndEncounter();
         //end PC's turn
         gv.touchEnabled = true;
         animationState = AnimationState.None;
         endPcTurn(true);
     }
     else if (animationState == AnimationState.CreatureMissedAnimation)
     {
         drawMissAnimation = false;
         hitAnimationLocation = new Coordinate();
         gv.Invalidate();
         //check for end of encounter
         checkEndEncounter();
         gv.touchEnabled = true;
         animationState = AnimationState.None;
         //end PC's turn
         endPcTurn(true);
     }
     else if (animationState == AnimationState.CreatureMeleeAttackAnimation)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         doStandardCreatureAttack();
     }
     else if (animationState == AnimationState.PcHitAnimation)
     {
         drawHitAnimation = false;
         hitAnimationLocation = new Coordinate();
         gv.Invalidate();
         animationState = AnimationState.None;
         endCreatureTurn();
     }
     else if (animationState == AnimationState.PcMissedAnimation)
     {
         drawMissAnimation = false;
         hitAnimationLocation = new Coordinate();
         gv.Invalidate();
         animationState = AnimationState.None;
         endCreatureTurn();
     }
     else if (animationState == AnimationState.PcRangedAttackAnimation)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         Player pc = mod.playerList[currentPlayerIndex];
         //do projectile next
         drawProjectileAnimation = true;
         projectileAnimationLocation = new Coordinate(pc.combatLocX * gv.squareSize, pc.combatLocY * gv.squareSize);
         //load projectile image
         projectile = gv.cc.LoadBitmap(mod.getItemByResRefForInfo(pc.AmmoRefs.resref).projectileSpriteFilename);
         if (pc.combatLocY < targetHighlightCenterLocation.Y)
         {
             projectile = gv.cc.FlipHorz(projectile);
         }
         //reset animation frame counter
         animationFrameIndex = 0;
         gv.Invalidate();
         animationState = AnimationState.PcRangedProjectileAnimation;
         gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
     }
     else if (animationState == AnimationState.PcRangedProjectileAnimation)
     {
         Player pc = mod.playerList[currentPlayerIndex];
         //if at target, do ending
         if ((projectileAnimationLocation.X == targetHighlightCenterLocation.X * gv.squareSize) && (projectileAnimationLocation.Y == targetHighlightCenterLocation.Y * gv.squareSize))
         {
             drawProjectileAnimation = false;
             projectileAnimationLocation = new Coordinate();
             drawEndingAnimation = true;
             endingAnimationLocation = new Coordinate(targetHighlightCenterLocation.X * gv.squareSize, targetHighlightCenterLocation.Y * gv.squareSize);
             animationFrameIndex = 0;
             ending_fx = gv.cc.LoadBitmap(mod.getItemByResRefForInfo(pc.AmmoRefs.resref).spriteEndingFilename);
             gv.Invalidate();
             animationState = AnimationState.PcRangedEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
         else //if not at target, get new coordinate and keep going
         {
             //if frame is last, reset
             animationFrameIndex++;
             if (animationFrameIndex > 4) {animationFrameIndex = 0;}
             //get next coordinate
             projectileAnimationLocation = GetNextProjectileCoordinate(new Coordinate(pc.combatLocX, pc.combatLocY), targetHighlightCenterLocation);
             gv.Invalidate();
             animationState = AnimationState.PcRangedProjectileAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
     }
     else if (animationState == AnimationState.PcRangedEndingAnimation)
     {
         Player pc = mod.playerList[currentPlayerIndex];
         if ((animationFrameIndex < 3) && (!mod.getItemByResRefForInfo(pc.MainHandRefs.resref).spriteEndingFilename.Equals("none")))
         {
             animationFrameIndex++;
             gv.Invalidate();
             animationState = AnimationState.PcRangedEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
         else //if not at target, get new coordinate and keep going
         {
             drawEndingAnimation = false;
             endingAnimationLocation = new Coordinate();
             animationFrameIndex = 0;
             //loop through 4 times
             gv.Invalidate();
             animationState = AnimationState.None;
             gv.touchEnabled = true;
             //Player pc = mod.playerList.get(currentPlayerIndex);
             doCombatAttack(pc);
         }
     }
     else if (animationState == AnimationState.PcCastAttackAnimation)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         Player pc = mod.playerList[currentPlayerIndex];
         //do projectile next
         drawProjectileAnimation = true;
         projectileAnimationLocation = new Coordinate(pc.combatLocX * gv.squareSize, pc.combatLocY * gv.squareSize);
         //load projectile image
         projectile = gv.cc.LoadBitmap(gv.cc.currentSelectedSpell.spriteFilename);
         if (pc.combatLocY < targetHighlightCenterLocation.Y)
         {
             projectile = gv.cc.FlipHorz(projectile);
         }
         //reset animation frame counter
         animationFrameIndex = 0;
         gv.Invalidate();
         animationState = AnimationState.PcCastProjectileAnimation;
         gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         //play cast projectile sound
         gv.PlaySound(gv.cc.currentSelectedSpell.spellStartSound);
     }
     else if (animationState == AnimationState.PcCastProjectileAnimation)
     {
         Player pc = mod.playerList[currentPlayerIndex];
         //if at target, do ending
         if ((projectileAnimationLocation.X == targetHighlightCenterLocation.X * gv.squareSize) && (projectileAnimationLocation.Y == targetHighlightCenterLocation.Y * gv.squareSize))
         {
             drawProjectileAnimation = false;
             projectileAnimationLocation = new Coordinate();
             drawEndingAnimation = true;
             endingAnimationLocation = new Coordinate(targetHighlightCenterLocation.X * gv.squareSize, targetHighlightCenterLocation.Y * gv.squareSize);
             animationFrameIndex = 0;
             ending_fx = gv.cc.LoadBitmap(gv.cc.currentSelectedSpell.spriteEndingFilename);
             gv.Invalidate();
             animationState = AnimationState.PcCastEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
             //play cast ending sound
             gv.PlaySound(gv.cc.currentSelectedSpell.spellEndSound);
         }
         else //if not at target, get new coordinate and keep going
         {
             //if frame is last, reset
             animationFrameIndex++;
             if (animationFrameIndex > 4) {animationFrameIndex = 0;}
             //get next coordinate
             projectileAnimationLocation = GetNextProjectileCoordinate(new Coordinate(pc.combatLocX, pc.combatLocY), targetHighlightCenterLocation);
             gv.Invalidate();
             animationState = AnimationState.PcCastProjectileAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
     }
     else if (animationState == AnimationState.PcCastEndingAnimation)
     {
         if (animationFrameIndex < 3)
         {
             animationFrameIndex++;
             gv.Invalidate();
             animationState = AnimationState.PcCastEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
         else //if not at target, get new coordinate and keep going
         {
             drawEndingAnimation = false;
             endingAnimationLocation = new Coordinate();
             animationFrameIndex = 0;
             //loop through 4 times
             gv.Invalidate();
             animationState = AnimationState.None;
             gv.touchEnabled = true;
             Player pc = mod.playerList[currentPlayerIndex];
             doCombatCast(pc);
         }
     }
     else if (animationState == AnimationState.CreatureRangedAttackAnimation)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         Creature crt = mod.currentEncounter.encounterCreatureList[creatureIndex];
         //do projectile next
         drawProjectileAnimation = true;
         projectileAnimationLocation = new Coordinate(crt.combatLocX * gv.squareSize, crt.combatLocY * gv.squareSize);
         //load projectile image
         projectile = gv.cc.LoadBitmap(crt.cr_projSpriteFilename);
         if (crt.combatLocY < creatureTargetLocation.Y)
         {
             projectile = gv.cc.FlipHorz(projectile);
         }
         //reset animation frame counter
         animationFrameIndex = 0;
         gv.Invalidate();
         animationState = AnimationState.CreatureRangedProjectileAnimation;
         gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
     }
     else if (animationState == AnimationState.CreatureRangedProjectileAnimation)
     {
         Creature crt = mod.currentEncounter.encounterCreatureList[creatureIndex];
         //if at target, do ending
         if ((projectileAnimationLocation.X == creatureTargetLocation.X * gv.squareSize) && (projectileAnimationLocation.Y == creatureTargetLocation.Y * gv.squareSize))
         {
             drawProjectileAnimation = false;
             projectileAnimationLocation = new Coordinate();
             drawEndingAnimation = true;
             endingAnimationLocation = new Coordinate(creatureTargetLocation.X * gv.squareSize, creatureTargetLocation.Y * gv.squareSize);
             animationFrameIndex = 0;
             ending_fx = gv.cc.LoadBitmap(crt.cr_spriteEndingFilename);
             gv.Invalidate();
             animationState = AnimationState.CreatureRangedEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
         else //if not at target, get new coordinate and keep going
         {
             //if frame is last, reset
             animationFrameIndex++;
             if (animationFrameIndex > 4) {animationFrameIndex = 0;}
             //get next coordinate
             projectileAnimationLocation = GetNextProjectileCoordinate(new Coordinate(crt.combatLocX, crt.combatLocY), creatureTargetLocation);
             gv.Invalidate();
             animationState = AnimationState.CreatureRangedProjectileAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
     }
     else if (animationState == AnimationState.CreatureRangedEndingAnimation)
     {
         Creature crt = mod.currentEncounter.encounterCreatureList[creatureIndex];
         if ((animationFrameIndex < 3) && (!crt.cr_spriteEndingFilename.Equals("none")))
         {
             animationFrameIndex++;
             gv.Invalidate();
             animationState = AnimationState.CreatureRangedEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
         else //if not at target, get new coordinate and keep going
         {
             drawEndingAnimation = false;
             endingAnimationLocation = new Coordinate();
             animationFrameIndex = 0;
             //loop through 4 times
             gv.Invalidate();
             animationState = AnimationState.None;
             //touchEnabled = true;
             doStandardCreatureAttack();
         }
     }
     else if (animationState == AnimationState.CreatureCastAttackAnimation)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         Creature crt = mod.currentEncounter.encounterCreatureList[creatureIndex];
         //do projectile next
         drawProjectileAnimation = true;
         projectileAnimationLocation = new Coordinate(crt.combatLocX * gv.squareSize, crt.combatLocY * gv.squareSize);
         //load projectile image
         projectile = gv.cc.LoadBitmap(gv.sf.SpellToCast.spriteFilename);
         if (crt.combatLocY < creatureTargetLocation.Y)
         {
             projectile = gv.cc.FlipHorz(projectile);
         }
         //reset animation frame counter
         animationFrameIndex = 0;
         gv.Invalidate();
         animationState = AnimationState.CreatureCastProjectileAnimation;
         gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         //play cast start sound
         gv.PlaySound(gv.sf.SpellToCast.spellStartSound);
     }
     else if (animationState == AnimationState.CreatureCastProjectileAnimation)
     {
         Creature crt = mod.currentEncounter.encounterCreatureList[creatureIndex];
         //if at target, do ending
         if ((projectileAnimationLocation.X == creatureTargetLocation.X * gv.squareSize) && (projectileAnimationLocation.Y == creatureTargetLocation.Y * gv.squareSize))
         {
             drawProjectileAnimation = false;
             projectileAnimationLocation = new Coordinate();
             drawEndingAnimation = true;
             endingAnimationLocation = new Coordinate(creatureTargetLocation.X * gv.squareSize, creatureTargetLocation.Y * gv.squareSize);
             animationFrameIndex = 0;
             ending_fx = gv.cc.LoadBitmap(gv.sf.SpellToCast.spriteEndingFilename);
             gv.Invalidate();
             animationState = AnimationState.CreatureCastEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
             //play cast ending sound
             gv.PlaySound(gv.sf.SpellToCast.spellEndSound);
         }
         else //if not at target, get new coordinate and keep going
         {
             //if frame is last, reset
             animationFrameIndex++;
             if (animationFrameIndex > 4) {animationFrameIndex = 0;}
             //get next coordinate
             projectileAnimationLocation = GetNextProjectileCoordinate(new Coordinate(crt.combatLocX, crt.combatLocY), creatureTargetLocation);
             gv.Invalidate();
             animationState = AnimationState.CreatureCastProjectileAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
     }
     else if (animationState == AnimationState.CreatureCastEndingAnimation)
     {
         if (animationFrameIndex < 3)
         {
             animationFrameIndex++;
             gv.Invalidate();
             animationState = AnimationState.CreatureCastEndingAnimation;
             gv.postDelayed("doAnimation", 2 * mod.combatAnimationSpeed);
         }
         else //if not at target, get new coordinate and keep going
         {
             drawEndingAnimation = false;
             endingAnimationLocation = new Coordinate();
             animationFrameIndex = 0;
             //loop through 4 times
             gv.Invalidate();
             animationState = AnimationState.None;
             //touchEnabled = true;
             doCreatureSpell();
         }
     }
     else if (animationState == AnimationState.CreatureThink)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         doCreatureTurnAfterDelay();
     }
     else if (animationState == AnimationState.CreatureMove)
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         Creature crt = mod.currentEncounter.encounterCreatureList[creatureIndex];
         CreatureDoesAttack(crt);
         //endCreatureTurn();
     }
 }
Пример #8
0
 public int CalcCreatureDefense(Creature crt)
 {
     int defense = crt.AC;
     if (crt.cr_status.Equals("Held"))
     {
         defense -= 4;
         gv.cc.addFloatyText(new Coordinate(crt.combatLocX, crt.combatLocY), "+4 att", "green");
     }
     return defense;
 }
Пример #9
0
        public void GeneralCaster(Creature crt)
        {
            gv.sf.SpellToCast = null;
            //just pick a random spell from KnownSpells
            //try a few times to pick a random spell that has enough SP
            for (int i = 0; i < 10; i++)
            {
                int rnd = gv.sf.RandInt(crt.knownSpellsTags.Count);
                Spell sp = mod.getSpellByTag(crt.knownSpellsTags[rnd-1]);
                if (sp != null)
                {
                    /*if (sf.frm.debugMode)
                    {
                        c.logText("KnownSpell: " + sp.SpellName, Color.Black);
                        c.logText(Environment.NewLine, Color.Black);
                    }*/
                    if (sp.costSP <= crt.sp)
                    {
                        gv.sf.SpellToCast = sp;
                        /*if (sf.frm.debugMode)
                        {
                            c.logText("SpellToCast: " + sf.SpellToCast.SpellName, Color.Black);
                            c.logText(Environment.NewLine, Color.Black);
                        }*/

                        if (gv.sf.SpellToCast.spellTargetType.Equals("Enemy"))
                        {
                            Player pc = targetClosestPC(crt);
                            gv.sf.CombatTarget = pc;
                            gv.sf.ActionToTake = "Cast";
                            break;
                        }
                        else if (gv.sf.SpellToCast.spellTargetType.Equals("PointLocation"))
                        {
                            //Player pc = targetClosestPC(crt);
                            //gv.sf.CombatTarget = new Coordinate(pc.combatLocX, pc.combatLocY); //we are using a Coordinate type because the selected spell is looking for a Coordinate type (square location)
                            Coordinate bestLoc = targetBestPointLocation(crt);
                            if (bestLoc == new Coordinate(-1,-1))
                            {
                                //didn't find a target so use closest PC
                                Player pc = targetClosestPC(crt);
                                gv.sf.CombatTarget = new Coordinate(pc.combatLocX, pc.combatLocY);
                            }
                            else
                            {
                                gv.sf.CombatTarget = targetBestPointLocation(crt);
                            }
                            gv.sf.ActionToTake = "Cast";
                            break;
                        }
                        else if (gv.sf.SpellToCast.spellTargetType.Equals("Friend"))
                        {
                            //target is another creature (currently assumed that spell is a heal spell)
                            Creature targetCrt = GetCreatureWithMostDamaged();
                            if (targetCrt != null)
                            {
                                gv.sf.CombatTarget = targetCrt;
                                gv.sf.ActionToTake = "Cast";
                                break;
                            }
                            else //didn't find a target that needs HP
                            {
                                gv.sf.SpellToCast = null;
                                continue;
                            }
                        }
                        else if (gv.sf.SpellToCast.spellTargetType.Equals("Self"))
                        {
                            //target is self (currently assumed that spell is a heal spell)
                            Creature targetCrt = crt;
                            if (targetCrt != null)
                            {
                                gv.sf.CombatTarget = targetCrt;
                                gv.sf.ActionToTake = "Cast";
                                break;
                            }
                        }
                        else //didn't find a target so set to null so that will use attack instead
                        {
                            gv.sf.SpellToCast = null;
                        }
                    }
                }
            }
            if (gv.sf.SpellToCast == null) //didn't find a spell that matched the criteria so use attack instead
            {
                Player pc = targetClosestPC(crt);
                gv.sf.CombatTarget = pc;
                gv.sf.ActionToTake = "Attack";
            }
        }
Пример #10
0
        public void doOnHitScriptBasedOnFilename(String filename, Creature crt, Player pc)
        {
            if (!filename.Equals("none"))
            {
                try
                {
                    if (filename.Equals("onHitBeetleFire.cs"))
                    {
                        float resist = (float)(1f - ((float)pc.damageTypeResistanceTotalFire / 100f));
                        float damage = (1 * gv.sf.RandInt(2)) + 0;
                        int fireDam = (int)(damage * resist);

                        if (mod.debugMode)
                        {
                            gv.cc.addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        gv.cc.addLogText("<font color='aqua'>" + pc.name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" + fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        pc.hp -= fireDam;
                    }

                    else if (filename.Equals("onHitMaceOfStunning.cs"))
                    {
                        int tryHold = gv.sf.RandInt(100);
                        if (tryHold > 50)
                        {
                            //attempt to hold PC
                            int saveChkRoll = gv.sf.RandInt(20);
                            int saveChk = saveChkRoll + crt.fortitude;
                            int DC = 15;
                            if (saveChk >= DC) //passed save check
                            {
                                gv.cc.addLogText("<font color='yellow'>" + crt.cr_name + " avoids stun (" + saveChkRoll + " + " + crt.fortitude + " >= " + DC + ")</font><BR>");
                            }
                            else
                            {
                                gv.cc.addLogText("<font color='red'>" + crt.cr_name + " is stunned by mace (" + saveChkRoll + " + " + crt.fortitude + " < " + DC + ")</font><BR>");
                                crt.cr_status = "Held";
                                Effect ef = mod.getEffectByTag("hold");
                                crt.AddEffectByObject(ef, mod.WorldTime);
                            }
                        }
                    }
                    else if (filename.Equals("onHitBeetleAcid.cs"))
                    {
                        float resist = (float)(1f - ((float)pc.damageTypeResistanceTotalAcid / 100f));
                        float damage = (1 * gv.sf.RandInt(2)) + 0;
                        int acidDam = (int)(damage * resist);

                        if (mod.debugMode)
                        {
                            gv.cc.addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                    + " acidDam = " + acidDam + "</font>" +
                                    "<BR>");
                        }
                        gv.cc.addLogText("<font color='aqua'>" + pc.name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='lime'>" + acidDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        pc.hp -= acidDam;

                        //attempt to hold PC
                        int saveChkRoll = gv.sf.RandInt(20);
                        //int saveChk = saveChkRoll + target.Will;
                        int saveChk = saveChkRoll + pc.fortitude;
                        int DC = 10;
                        if (saveChk >= DC) //passed save check
                        {
                            gv.cc.addLogText("<font color='yellow'>" + pc.name + " avoids the acid stun (" + saveChkRoll + " + " + pc.fortitude + " >= " + DC + ")</font><BR>");
                        }
                        else
                        {
                            gv.cc.addLogText("<font color='red'>" + pc.name + " is held by an acid stun (" + saveChkRoll + " + " + pc.fortitude + " < " + DC + ")</font><BR>");
                            pc.charStatus = "Held";
                            Effect ef = mod.getEffectByTag("hold");
                            pc.AddEffectByObject(ef, mod.WorldTime);
                        }
                    }
                    else if (filename.Equals("onHitOneFire.cs"))
                    {
                        float resist = (float)(1f - ((float)crt.damageTypeResistanceValueFire / 100f));
                        float damage = 1.0f;
                        int fireDam = (int)(damage * resist);

                        if (mod.debugMode)
                        {
                            gv.cc.addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        gv.cc.addLogText("<font color='aqua'>" + crt.cr_name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" + fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        crt.hp -= fireDam;
                    }
                    else if (filename.Equals("onHitOneTwoFire.cs"))
                    {
                        float resist = (float)(1f - ((float)crt.damageTypeResistanceValueFire / 100f));
                        float damage = (1 * gv.sf.RandInt(2)) + 0;
                        int fireDam = (int)(damage * resist);

                        if (mod.debugMode)
                        {
                            gv.cc.addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        gv.cc.addLogText("<font color='aqua'>" + crt.cr_name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" + fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        crt.hp -= fireDam;
                    }
                    else if (filename.Equals("onHitTwoThreeFire.cs"))
                    {
                        float resist = (float)(1f - ((float)crt.damageTypeResistanceValueFire / 100f));
                        float damage = (1 * gv.sf.RandInt(2)) + 1;
                        int fireDam = (int)(damage * resist);

                        if (mod.debugMode)
                        {
                            gv.cc.addLogText("<font color='yellow'>" + "resist = " + resist + " damage = " + damage
                                        + " fireDam = " + fireDam + "</font>" +
                                        "<BR>");
                        }
                        gv.cc.addLogText("<font color='aqua'>" + crt.cr_name + "</font>" +
                                "<font color='white'>" + " is burned for " + "</font>" +
                                "<font color='red'>" + fireDam + "</font>" +
                                "<font color='white'>" + " hit point(s)" + "</font>" +
                                "<BR>");
                        crt.hp -= fireDam;
                    }
                    else if (filename.Equals("onHitPcPoisonedLight.cs"))
                    {
                        int saveChkRoll = gv.sf.RandInt(20);
                        int saveChk = saveChkRoll + pc.reflex;
                        int DC = 13;
                        if (saveChk >= DC) //passed save check
                        {
                            gv.cc.addLogText("<font color='yellow'>" + pc.name + " avoids being poisoned" + "</font>" +
                                    "<BR>");
                            if (mod.debugMode)
                            {
                                gv.cc.addLogText("<font color='yellow'>" + saveChkRoll + " + " + pc.reflex + " >= " + DC + "</font>" +
                                            "<BR>");
                            }
                        }
                        else //failed check
                        {
                            gv.cc.addLogText("<font color='red'>" + pc.name + " is poisoned" + "</font>" + "<BR>");
                            Effect ef = mod.getEffectByTag("poisonedLight");
                            pc.AddEffectByObject(ef, mod.WorldTime);
                        }
                    }
                    else if (filename.Equals("onHitPcPoisonedMedium.cs"))
                    {
                        int saveChkRoll = gv.sf.RandInt(20);
                        int saveChk = saveChkRoll + pc.reflex;
                        int DC = 16;
                        if (saveChk >= DC) //passed save check
                        {
                            gv.cc.addLogText("<font color='yellow'>" + pc.name + " avoids being poisoned" + "</font>" +
                                    "<BR>");
                            if (mod.debugMode)
                            {
                                gv.cc.addLogText("<font color='yellow'>" + saveChkRoll + " + " + pc.reflex + " >= " + DC + "</font>" +
                                            "<BR>");
                            }
                        }
                        else //failed check
                        {
                            gv.cc.addLogText("<font color='red'>" + pc.name + " is poisoned" + "</font>" + "<BR>");
                            Effect ef = mod.getEffectByTag("poisonedMedium");
                            pc.AddEffectByObject(ef, mod.WorldTime);
                        }
                    }
                }
                catch (Exception ex)
                {
                    //IBMessageBox.Show(game, "failed to run script");
                }
            }
        }
Пример #11
0
        public int CalcCreatureDamageToPc(Player pc, Creature crt)
        {
            int dDam = crt.cr_damageDie;
            float damage = (crt.cr_damageNumDice * gv.sf.RandInt(dDam)) + crt.cr_damageAdder;
            if (damage < 0)
            {
                damage = 0;
            }

            float resist = 0;

            if (crt.cr_typeOfDamage.Equals("Acid"))
            {
                resist = (float)(1f - ((float)pc.damageTypeResistanceTotalAcid / 100f));
            }
            else if (crt.cr_typeOfDamage.Equals("Normal"))
            {
                resist = (float)(1f - ((float)pc.damageTypeResistanceTotalNormal / 100f));
            }
            else if (crt.cr_typeOfDamage.Equals("Cold"))
            {
                resist = (float)(1f - ((float)pc.damageTypeResistanceTotalCold / 100f));
            }
            else if (crt.cr_typeOfDamage.Equals("Electricity"))
            {
                resist = (float)(1f - ((float)pc.damageTypeResistanceTotalElectricity / 100f));
            }
            else if (crt.cr_typeOfDamage.Equals("Fire"))
            {
                resist = (float)(1f - ((float)pc.damageTypeResistanceTotalFire / 100f));
            }
            else if (crt.cr_typeOfDamage.Equals("Magic"))
            {
                resist = (float)(1f - ((float)pc.damageTypeResistanceTotalMagic / 100f));
            }
            else if (crt.cr_typeOfDamage.Equals("Poison"))
            {
                resist = (float)(1f - ((float)pc.damageTypeResistanceTotalPoison / 100f));
            }

            int totalDam = (int)(damage * resist);
            if (totalDam < 0)
            {
                totalDam = 0;
            }

            return totalDam;
        }
Пример #12
0
 public void doCreatureTurn()
 {
     canMove = true;
     //gv.cc.logScrollOffset = 0;
     Creature crt = mod.currentEncounter.encounterCreatureList[creatureIndex];
     //do onTurn LT
     gv.cc.doLogicTreeBasedOnTag(gv.mod.currentEncounter.OnStartCombatTurnLogicTree, gv.mod.currentEncounter.OnStartCombatTurnParms);
     if ((crt.hp > 0) && (!crt.cr_status.Equals("Held")))
     {
         creatureToAnimate = null;
         playerToAnimate = null;
         gv.Invalidate();
         animationState = AnimationState.CreatureThink;
         gv.postDelayed("doAnimation", 5 * mod.combatAnimationSpeed);
     }
     else
     {
         endCreatureTurn();
     }
 }
Пример #13
0
 public int CalcCreatureAttackModifier(Creature crt)
 {
     if ((crt.cr_category.Equals("Ranged")) && (isAdjacentPc(crt)))
     {
         gv.cc.addLogText("<font color='yellow'>" + "-4 ranged attack penalty" + "</font>" +
                 "<BR>");
         gv.cc.addLogText("<font color='yellow'>" + "with enemies in melee range" + "</font>" +
                 "<BR>");
         gv.cc.floatyTextOn = true;
         gv.cc.addFloatyText(new Coordinate(crt.combatLocX, crt.combatLocY), "-4 att", "yellow");
         gv.postDelayed("doFloatyText", 100);
         return crt.cr_att - 4;
     }
     else //melee weapon used
     {
         return crt.cr_att;
     }
 }
Пример #14
0
        public void doCreatureAI(Creature crt)
        {
            //These are the current generic AI types
            //BasicAttacker:          basic attack (ranged or melee)
            //Healer:                 heal Friend(s) until out of SP
            //BattleHealer:           heal Friend(s) and/or attack
            //DamageCaster:           cast damage spells
            //BattleDamageCaster:     cast damage spells and/or attack
            //DebuffCaster:           cast debuff spells
            //BattleDebuffCaster:     cast debuff spells and/or attack
            //GeneralCaster:          cast any of their known spells by random
            //BattleGeneralCaster:    cast any of their known spells by random and/or attack

            if (crt.cr_ai.Equals("BasicAttacker"))
            {
                /*if (sf.frm.debugMode)
                {
                    c.logText(crt.Name, Color.LightGray);
                    c.logText(" is a BasicAttacker", Color.Black);
                    c.logText(Environment.NewLine, Color.Black);
                }*/
                BasicAttacker(crt);
            }
            else if (crt.cr_ai.Equals("GeneralCaster"))
            {
                /*if (sf.frm.debugMode)
                {
                    c.logText(crt.Name, Color.LightGray);
                    c.logText(" is a GeneralCaster", Color.Black);
                    c.logText(Environment.NewLine, Color.Black);
                }*/
                GeneralCaster(crt);
            }
            else
            {
                /*if (sf.frm.debugMode)
                {
                    c.logText(crt.Name, Color.LightGray);
                    c.logText(" is a BasicAttacker", Color.Black);
                    c.logText(Environment.NewLine, Color.Black);
                }*/
                BasicAttacker(crt);
            }
        }
Пример #15
0
        public void CreatureCastsSpell(Creature crt)
        {
            Coordinate pnt = new Coordinate();
            if (gv.sf.CombatTarget is Player)
            {
                Player pc = (Player)gv.sf.CombatTarget;
                pnt = new Coordinate(pc.combatLocX, pc.combatLocY);
            }
            else if (gv.sf.CombatTarget is Creature)
            {
                Creature crtTarget = (Creature)gv.sf.CombatTarget;
                pnt = new Coordinate(crtTarget.combatLocX, crtTarget.combatLocY);
            }
            else if (gv.sf.CombatTarget is Coordinate)
            {
                pnt = (Coordinate)gv.sf.CombatTarget;
            }
            else //do not understand, what is the target
            {
                //Toast.makeText(gv.gameContext, "can't figure out target.", Toast.LENGTH_SHORT).show();
                return;
            }
            int endX = pnt.X * gv.squareSize + (gv.squareSize / 2);
            int endY = pnt.Y * gv.squareSize + (gv.squareSize / 2);
            int startX = crt.combatLocX * gv.squareSize + (gv.squareSize / 2);
            int startY = crt.combatLocY * gv.squareSize + (gv.squareSize / 2);
            if ((getDistance(pnt, new Coordinate(crt.combatLocX, crt.combatLocY)) <= gv.sf.SpellToCast.range)
                    && (isVisibleLineOfSight(new Coordinate(endX, endY), new Coordinate(startX, startY))))
            {
                if ((pnt.X < crt.combatLocX) && (!crt.combatFacingLeft)) //attack left
                {
                    crt.token= gv.cc.flip(crt.token);
                    crt.combatFacingLeft = true;
                }
                else if ((pnt.X > crt.combatLocX) && (crt.combatFacingLeft)) //attack right
                {
                    crt.token= gv.cc.flip(crt.token);
                    crt.combatFacingLeft = false;
                }
                creatureTargetLocation = pnt;
                //touchEnabled = false;
                creatureToAnimate = crt;
                playerToAnimate = null;
                gv.Invalidate();
                animationState = AnimationState.CreatureCastAttackAnimation;
                gv.postDelayed("doAnimation", 5 * mod.combatAnimationSpeed);

            }
            else
            {
                //#region Do a Melee or Ranged Attack
                Player pc = targetClosestPC(crt);
                gv.sf.CombatTarget = pc;
                CreatureDoesAttack(crt);
            }
        }
Пример #16
0
 public bool isAdjacentPc(Creature crt)
 {
     foreach (Player pc in mod.playerList)
     {
         if (getDistance(new Coordinate(pc.combatLocX,pc.combatLocY), new Coordinate(crt.combatLocX,crt.combatLocY)) == 1)
         {
             return true;
         }
     }
     return false;
 }
Пример #17
0
 public void CreatureDoesAttack(Creature crt)
 {
     if (gv.sf.CombatTarget != null)
     {
         Player pc = (Player)gv.sf.CombatTarget;
         int endX = pc.combatLocX * gv.squareSize + (gv.squareSize / 2);
         int endY = pc.combatLocY * gv.squareSize + (gv.squareSize / 2);
         int startX = crt.combatLocX * gv.squareSize + (gv.squareSize / 2);
         int startY = crt.combatLocY * gv.squareSize + (gv.squareSize / 2);
         // determine if ranged or melee
         if ((crt.cr_category.Equals("Ranged"))
                 && (CalcDistance(crt.combatLocX, crt.combatLocY, pc.combatLocX, pc.combatLocY) <= crt.cr_attRange)
                 && (isVisibleLineOfSight(new Coordinate(endX, endY), new Coordinate(startX, startY))))
         {
             //Point starting = new Point((crt_pt.CombatLocation.X * gm._squareSize) + (gm._squareSize / 2), (crt_pt.CombatLocation.Y * gm._squareSize) + (gm._squareSize / 2));
             //Point ending = new Point((char_pt.CombatLocation.X * gm._squareSize) + (gm._squareSize / 2), (char_pt.CombatLocation.Y * gm._squareSize) + (gm._squareSize / 2));
             //frm.currentCombat.playCreatureAttackSound(crt_pt);
             //play attack sound for ranged
             gv.PlaySound(crt.cr_attackSound);
             //frm.currentCombat.drawProjectile(starting, ending, crt_pt.ProjectileSpriteFilename);
             if ((pc.combatLocX < crt.combatLocX) && (!crt.combatFacingLeft)) //attack left
             {
                 crt.token= gv.cc.flip(crt.token);
                 crt.combatFacingLeft = true;
             }
             else if ((pc.combatLocX > crt.combatLocX) && (crt.combatFacingLeft)) //attack right
             {
                 crt.token= gv.cc.flip(crt.token);
                 crt.combatFacingLeft = false;
             }
             if (crt.hp > 0)
             {
                 //doStandardCreatureAttack(crt, pc);
                 creatureToAnimate = crt;
                 playerToAnimate = null;
                 gv.Invalidate();
                 creatureTargetLocation = new Coordinate(pc.combatLocX, pc.combatLocY);
                 animationState = AnimationState.CreatureRangedAttackAnimation;
                 gv.postDelayed("doAnimation", 5 * mod.combatAnimationSpeed);
             }
             else
             {
                 //skip this guys turn
             }
         }
         else if ((crt.cr_category.Equals("Melee"))
                 && (CalcDistance(crt.combatLocX, crt.combatLocY, pc.combatLocX, pc.combatLocY) <= crt.cr_attRange))
         {
             if ((pc.combatLocX < crt.combatLocX) && (!crt.combatFacingLeft)) //attack left
             {
                 crt.token= gv.cc.flip(crt.token);
                 crt.combatFacingLeft = true;
             }
             else if ((pc.combatLocX > crt.combatLocX) && (crt.combatFacingLeft)) //attack right
             {
                 crt.token= gv.cc.flip(crt.token);
                 crt.combatFacingLeft = false;
             }
             if (crt.hp > 0)
             {
                 //doStandardCreatureAttack(crt, pc);
                 creatureToAnimate = crt;
                 playerToAnimate = null;
                 gv.Invalidate();
                 animationState = AnimationState.CreatureMeleeAttackAnimation;
                 gv.postDelayed("doAnimation", 5 * mod.combatAnimationSpeed);
                 //creatureTurnState = "attackAnim";
             }
             else
             {
                 //skip this guys turn
             }
         }
         else //not in range for attack so MOVE
         {
             CreatureMoves();
         }
     }
     else //no target so move instead
     {
         CreatureMoves();
     }
 }
Пример #18
0
        public int CalcPcDamageToCreature(Player pc, Creature crt)
        {
            int damModifier = 0;
            int adder = 0;
            bool melee = false;
            if ((mod.getItemByResRefForInfo(pc.MainHandRefs.resref).category.Equals("Melee"))
                    || (pc.MainHandRefs.name.Equals("none"))
                    || (mod.getItemByResRefForInfo(pc.AmmoRefs.resref).name.Equals("none")))
            {
                melee = true;
                damModifier = (pc.strength - 10) / 2;
                //if has critical strike trait use dexterity for damage modifier in melee if greater than strength modifier
                if (gv.sf.hasTrait(pc, "criticalstrike"))
                {
                    int damModifierDex = (pc.dexterity - 10) / 4;
                    if (damModifierDex > damModifier)
                    {
                        damModifier = (pc.dexterity - 10) / 2;
                    }
                }
            }
            else //ranged weapon used
            {
                damModifier = 0;
                if (gv.sf.hasTrait(pc, "preciseshot2"))
                {
                    damModifier += 2;
                    gv.cc.addLogText("<font color='lime'> PreciseShotL2: +2 damage</font><BR>");
                }
                else if (gv.sf.hasTrait(pc, "preciseshot"))
                {
                    damModifier++;
                    gv.cc.addLogText("<font color='lime'> PreciseShotL1: +1 damage</font><BR>");
                }

            }

            int dDam = mod.getItemByResRefForInfo(pc.MainHandRefs.resref).damageDie;
            float damage = (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).damageNumDice * gv.sf.RandInt(dDam)) + damModifier + adder + mod.getItemByResRefForInfo(pc.MainHandRefs.resref).damageAdder;
            if (damage < 0)
            {
                damage = 0;
            }
            Item it = mod.getItemByResRefForInfo(pc.AmmoRefs.resref);
            if (it != null)
            {
                damage += mod.getItemByResRefForInfo(pc.AmmoRefs.resref).damageAdder;
            }

            float resist = 0;

            if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).typeOfDamage.Equals("Acid"))
            {
                resist = (float)(1f - ((float)crt.damageTypeResistanceValueAcid / 100f));
            }
            else if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).typeOfDamage.Equals("Normal"))
            {
                resist = (float)(1f - ((float)crt.damageTypeResistanceValueNormal / 100f));
            }
            else if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).typeOfDamage.Equals("Cold"))
            {
                resist = (float)(1f - ((float)crt.damageTypeResistanceValueCold / 100f));
            }
            else if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).typeOfDamage.Equals("Electricity"))
            {
                resist = (float)(1f - ((float)crt.damageTypeResistanceValueElectricity / 100f));
            }
            else if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).typeOfDamage.Equals("Fire"))
            {
                resist = (float)(1f - ((float)crt.damageTypeResistanceValueFire / 100f));
            }
            else if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).typeOfDamage.Equals("Magic"))
            {
                resist = (float)(1f - ((float)crt.damageTypeResistanceValueMagic / 100f));
            }
            else if (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).typeOfDamage.Equals("Poison"))
            {
                resist = (float)(1f - ((float)crt.damageTypeResistanceValuePoison / 100f));
            }

            int totalDam = (int)(damage * resist);
            if (totalDam < 0)
            {
                totalDam = 0;
            }
            //if doing sneak attack, does extra damage
            if ((pc.steathModeOn) && (melee))
            {
                if (pc.knownTraitsTags.Contains("sneakattack"))
                {
                    //+1d6 for every 2 levels after level 1
                    int multiplier = ((pc.classLevel - 1) / 2) + 1;
                    int adding = 0;
                    for (int i = 0; i < multiplier; i++)
                    {
                        adding += gv.sf.RandInt(6);
                    }
                    totalDam += adding;
                    gv.cc.addLogText("<font color='lime'> sneak attack: +" + adding + " damage</font><BR>");
                    if (mod.debugMode) //SD_20131102
                    {
                        //gv.cc.addLogText("<font color='yellow'> sneak attack: +" + adding + " damage</font><BR>");
                    }
                }
            }
            return totalDam;
        }
Пример #19
0
        public bool doActualCreatureAttack(Player pc, Creature crt, int attackNumber)
        {
            int attackRoll = gv.sf.RandInt(20);
            int attackMod = CalcCreatureAttackModifier(crt);
            int defense = CalcPcDefense(pc, crt);
            int damage = CalcCreatureDamageToPc(pc, crt);
            int attack = attackRoll + attackMod;

            if ((attack >= defense) || (attackRoll == 20))
            {
                pc.hp = pc.hp - damage;
                gv.cc.addLogText("<font color='silver'>" + crt.cr_name + "</font>" +
                        "<font color='white'>" + " attacks " + "</font>" +
                        "<font color='aqua'>" + pc.name + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + " and HITS (" + "</font>" +
                        "<font color='red'>" + damage + "</font>" +
                        "<font color='white'>" + " damage)" + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + attackRoll + " + " + attackMod + " >= " + defense + "</font>" +
                        "<BR>");

                //#region onScoringHit script of creature
                doOnHitScriptBasedOnFilename(crt.onScoringHit, crt, pc);
                //#endregion

                //Draw floaty text showing damage above PC

                int txtH = (int)gv.drawFontReg.Height;
                int shiftUp = 0 - (attackNumber * txtH);
                floatyTextOn = true;
                gv.cc.addFloatyText(new Coordinate(pc.combatLocX, pc.combatLocY), damage + "", shiftUp);
                gv.postDelayed("doFloatyText", 100);

                if (pc.hp <= 0)
                {
                    gv.cc.addLogText("<font color='red'>" + pc.name + " drops down unconsciously!" + "</font>" +
                            "<BR>");
                    pc.charStatus = "Dead";
                }
                return true;
            }
            else
            {
                gv.cc.addLogText("<font color='silver'>" + crt.cr_name + "</font>" +
                        "<font color='white'>" + " attacks " + "</font>" +
                        "<font color='aqua'>" + pc.name + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + " and MISSES" + "</font>" +
                        "<BR>");
                gv.cc.addLogText("<font color='white'>" + attackRoll + " + " + attackMod + " < " + defense + "</font>" +
                        "<BR>");
                return false;
            }
        }
Пример #20
0
 public int CalcPcDefense(Player pc, Creature crt)
 {
     //pc.UpdateStats(this);
     int defense = pc.AC;
     if (pc.charStatus.Equals("Held"))
     {
         defense -= 4;
         gv.cc.addFloatyText(new Coordinate(pc.combatLocX, pc.combatLocY), "+4 att", "yellow");
     }
     return defense;
 }
Пример #21
0
        //called from outside to get next move location
        public Coordinate findNewPoint(Creature crt, Coordinate end)
        {
            foundEnd = false;
            Coordinate newPoint = new Coordinate(-1,-1);
            //set start value to 0
            values[crt.combatLocX,crt.combatLocY] = 0;
            foreach (Creature cr in mod.currentEncounter.encounterCreatureList)
            {
                if (cr != crt)
                grid[cr.combatLocX,cr.combatLocY] = 1;
            }
            foreach (Player p in mod.playerList)
            {
                if ((!p.charStatus.Equals("Dead")) && (p.hp > 0))
                {
                    grid[p.combatLocX,p.combatLocY] = 1;
                }
            }
            grid[crt.combatLocX,crt.combatLocY] = 2;
            grid[end.X,end.Y] = 3;
            buildPath();

            if (!foundEnd)
            {
                //do not build path for now so return (-1,-1), later add code for picking a spot to move
            }
            else
            {
                pathNodes.Add(new Coordinate(end.X, end.Y));
                for (int i = 0; i < values[end.X,end.Y]; i++)
                {
                    pathNodes.Add(getLowestNeighbor(pathNodes[pathNodes.Count - 1]));
                }
                //build list of path points
                newPoint = pathNodes[pathNodes.Count - 2];
            }
            return newPoint;
        }
Пример #22
0
 public void TargetAttack(Player pc)
 {
     if (isValidAttackTarget(pc))
     {
         if ((targetHighlightCenterLocation.X < pc.combatLocX) && (!pc.combatFacingLeft)) //attack left
         {
             pc.token = gv.cc.flip(pc.token);
             pc.combatFacingLeft = true;
         }
         else if ((targetHighlightCenterLocation.X > pc.combatLocX) && (pc.combatFacingLeft)) //attack right
         {
             pc.token = gv.cc.flip(pc.token);
             pc.combatFacingLeft = false;
         }
         gv.touchEnabled = false;
         creatureToAnimate = null;
         playerToAnimate = pc;
         gv.Invalidate();
         if ((mod.getItemByResRefForInfo(pc.MainHandRefs.resref).category.Equals("Melee"))
                 || (mod.getItemByResRefForInfo(pc.MainHandRefs.resref).name.Equals("none"))
                 || (mod.getItemByResRefForInfo(pc.AmmoRefs.resref).name.Equals("none")))
         {
             animationState = AnimationState.PcMeleeAttackAnimation;
         }
         else
         {
             //play attack sound for ranged
             gv.PlaySound(mod.getItemByResRefForInfo(pc.MainHandRefs.resref).itemOnUseSound);
             animationState = AnimationState.PcRangedAttackAnimation;
         }
         gv.postDelayed("doAnimation", 5 * mod.combatAnimationSpeed);
     }
 }
Пример #23
0
        //called from outside to get next move location
        public Coordinate findNewPoint(Creature crt, Coordinate end)
        {
            foundEnd = false;
            Coordinate newPoint = new Coordinate(-1, -1);
            //set start value to 0
            values[crt.combatLocX, crt.combatLocY] = 0;
            foreach (Creature cr in mod.currentEncounter.encounterCreatureList)
            {
                if (cr != crt)
                    grid[cr.combatLocX, cr.combatLocY] = 1;
            }
            foreach (Player p in mod.playerList)
            {
                if ((!p.charStatus.Equals("Dead")) && (p.hp > 0))
                {
                    grid[p.combatLocX, p.combatLocY] = 1;
                }
            }
            //find all props that have collision and set there square to 1
            /*TODO add props to encounters
            foreach (Prop prp in mod.currentEncounter.Props)
            {
                if  ( ((prp.HasCollision) && (prp.isActive)) || ((prp.isMover) && (prp.isActive)) )
                {
                    grid[prp.LocationX,prp.LocationY] = 1;
                }
            }*/
            grid[crt.combatLocX, crt.combatLocY] = 2; //2 marks the start point in the grid
            grid[end.X, end.Y] = 3; //3 marks the end point in the grid
            buildPath();

            if (!foundEnd)
            {
                //do not build path for now so return (-1,-1), later add code for picking a spot to move
            }
            else
            {
                pathNodes.Add(new Coordinate(end.X, end.Y));
                for (int i = 0; i < 9999; i++) //keep going until full path back to crt is built
                {
                    pathNodes.Add(getLowestNeighbor(pathNodes[pathNodes.Count - 1]));
                    if ((pathNodes[pathNodes.Count - 1].X == crt.combatLocX ) && (pathNodes[pathNodes.Count - 1].Y == crt.combatLocY ))
                    {
                        break;
                    }
                }
                //build list of path points
                newPoint = pathNodes[pathNodes.Count - 2];
            }
            return newPoint;
        }
Пример #24
0
        public Creature DeepCopy()
        {
            Creature copy = new Creature();
            copy.cr_tokenFilename = this.cr_tokenFilename;
            copy.combatFacingLeft = this.combatFacingLeft;
            copy.combatLocX = this.combatLocX;
            copy.combatLocY = this.combatLocY;
            copy.cr_name = this.cr_name;
            copy.cr_tag = this.cr_tag;
            copy.cr_resref = this.cr_resref;
            copy.cr_desc = this.cr_desc;
            copy.cr_level = this.cr_level;
            copy.hp = this.hp;
            copy.hpMax = this.hpMax;
            copy.sp = this.sp;
            copy.cr_XP = this.cr_XP;
            copy.AC = this.AC;
            copy.cr_status = this.cr_status;
            copy.cr_att = this.cr_att;
            copy.cr_attRange = this.cr_attRange;
            copy.cr_damageNumDice = this.cr_damageNumDice;
            copy.cr_damageDie = this.cr_damageDie;
            copy.cr_damageAdder = this.cr_damageAdder;
            copy.cr_category = this.cr_category;
            copy.cr_projSpriteFilename = this.cr_projSpriteFilename;
            copy.cr_spriteEndingFilename = this.cr_spriteEndingFilename;
            copy.cr_attackSound = this.cr_attackSound;
            copy.cr_numberOfAttacks = this.cr_numberOfAttacks;
            copy.cr_ai = this.cr_ai;
            copy.fortitude = this.fortitude;
            copy.will = this.will;
            copy.reflex = this.reflex;
            copy.damageTypeResistanceValueAcid = this.damageTypeResistanceValueAcid;
            copy.damageTypeResistanceValueNormal = this.damageTypeResistanceValueNormal;
            copy.damageTypeResistanceValueCold = this.damageTypeResistanceValueCold;
            copy.damageTypeResistanceValueElectricity = this.damageTypeResistanceValueElectricity;
            copy.damageTypeResistanceValueFire = this.damageTypeResistanceValueFire;
            copy.damageTypeResistanceValueMagic = this.damageTypeResistanceValueMagic;
            copy.damageTypeResistanceValuePoison = this.damageTypeResistanceValuePoison;
            copy.cr_typeOfDamage = this.cr_typeOfDamage;
            copy.onScoringHit = this.onScoringHit;
            copy.onScoringHitParms = this.onScoringHitParms;
            copy.onDeathLogicTree = this.onDeathLogicTree;
            copy.onDeathParms = this.onDeathParms;
            copy.cr_effectsList = new List<Effect>();

            copy.knownSpellsTags = new List<string>();
            foreach (string s in this.knownSpellsTags)
            {
                copy.knownSpellsTags.Add(s);
            }

            copy.CreatureLocalInts = new List<LocalInt>();
            foreach (LocalInt l in this.CreatureLocalInts)
            {
                LocalInt Lint = new LocalInt();
                Lint.Key = l.Key;
                Lint.Value = l.Value;
                copy.CreatureLocalInts.Add(Lint);
            }

            copy.CreatureLocalStrings = new List<LocalString>();
            foreach (LocalString l in this.CreatureLocalStrings)
            {
                LocalString Lstr = new LocalString();
                Lstr.Key = l.Key;
                Lstr.Value = l.Value;
                copy.CreatureLocalStrings.Add(Lstr);
            }
            return copy;
        }