Slowdive's Little Daily Blog

Discuss anything in general about the IceBlink Engine + Toolset project (or anything else) here.
User avatar
Dorateen
Posts: 262
Joined: Thu Jan 16, 2020 3:03 pm

Re: Slowdive's Little Daily Blog

Post by Dorateen »

Good start to the adventure, your party looks quite capable.

I noticed on its turn, the spider did not cast web. Is that because your characters moved in to melee range?

Regarding the 3d view backdrops, that looks like the way to go. I imagine it is even easier for indoor/dungeon maps where a builder does not have to worry about a sky/time of day background image.
User avatar
slowdive
Site Admin
Posts: 485
Joined: Wed Jan 15, 2020 4:37 am

Re: Slowdive's Little Daily Blog

Post by slowdive »

I'll have to look at the spider encounter again to see what happened. If it is a GeneralCaster and has 100% casting, it should cast a spell unless there is no spell that passes the criteria for optimal use (may try and save SP for a later round unless if optimal).

You don't have to use the directional/time of day backdrop on exterior areas, it is just an optional thing that is nice to have. There are also overlay wall tiles that can add doors, windows, shelves, containers, furniture, weapon racks, light coming down from cave ceiling opening, etc. on top of a normal wall tile.

I just revised the load/save system in IB v204. It now has 10 save slots for the player. It also has a "quicksave" slot that can be made from the save menu or from F5. I also have an "autosave" slot that is triggered before each encounter if the module author has the allowAutosave flag set to true in the module's settings (Hearkenwold has it set to true, was that intentional?). If you try and click on the "autosave" slot in the save game dialog, it gives you a message that says (and it doesn't allow the player to use the slot for saving, only loading):

gv.sf.MessageBoxHtml("This save slot is used by the game engine only. Before each encounter, an autosave is made if the module author allows it (module setting allowAutosave = true/false). This module has allowAutosave set to: " + gv.mod.allowAutosave);
IB34.PNG
IB34.PNG (594.33 KiB) Viewed 1269 times
User avatar
slowdive
Site Admin
Posts: 485
Joined: Wed Jan 15, 2020 4:37 am

Re: Slowdive's Little Daily Blog

Post by slowdive »

Dorateen wrote: Sun Oct 17, 2021 2:24 pm I noticed on its turn, the spider did not cast web. Is that because your characters moved in to melee range?
So it looks like I was only checking for effects from the spells effect list and not for the event where the spell uses the spellEffectTag instead of the spellEffectTagList. IBbasic only uses the spellEffectTagList so the code I copied over was ignoring the old way of using the spellEffectTag. The benefit of switching to the list is that you could have a spell that does multiple types of effects such as a spell that does minor healing and bless, or sleep and blast of light, etc. Either way, I changed the General Caster AI to look for both instance (the old and new methods) so now Hearkenwold is working correctly (I tested it out).

SIDE NOTE: I was able to turn back on all the 3d view code for IBbasic and test it out. I still need to turn back on the toolset parts, but everything works fine so far. Once it all is back in and checks out, I'll add the code to IB v204 as well.
User avatar
slowdive
Site Admin
Posts: 485
Joined: Wed Jan 15, 2020 4:37 am

Re: Slowdive's Little Daily Blog

Post by slowdive »

I'm trying to track down a few attack modifier calculation bugs so no streaming tonight. I not sure if modifiers from items or effects are being added into the attack modifiers so I'll need to verify that and fix if needed.
User avatar
Dorateen
Posts: 262
Joined: Thu Jan 16, 2020 3:03 pm

Re: Slowdive's Little Daily Blog

Post by Dorateen »

Do you think it is something in the latest builds? I had been testing a lot in 200, and then upgraded to 203 at the end just before I posted the module. I don't recall seeing attack modifiers not being applied. But then, I was also running higher level characters, and it is probably more noticeable in the early game.

edit: Not very extensive, but I just tested in build 203, a fighter with BAB 10 unarmed. I equipped a +1 short sword, and the character sheet shows a BAB of 11. I then fought a battle, and his attack rolls showed +11.
User avatar
slowdive
Site Admin
Posts: 485
Joined: Wed Jan 15, 2020 4:37 am

Re: Slowdive's Little Daily Blog

Post by slowdive »

It looks like the bonuses from items was being counted correctly, but not from effects such as prayer. I tried to clean up the calculation a bit so it is easier to follow the code going forward. I think I have everything accounted for now and I updated the d20 screen to show all the modifiers.

Code: Select all

public int CalcPcAttackModifier(Player pc, Creature crt, bool isMainHand)
        {
            //int modifier = 0;
            int situationalModifier = 0;
                        
            int equippedItemsMod = 0;
            int ammoMod = 0;
            int bab = pc.baseAttBonus;
            int babEffectMod = 0;
            int attributeMod = 0;
            int fromBehindMod = 0;
            int targetHeldMod = 0;
            int adjacentEnemyPenalty = 0;
            int sneakAttackMod = 0;
            int twoWeaponMod = 0;
            int poorVisionMod = gv.mod.poorVisionModifier;
            int preciseShotAdder = 0;
            int hardToKillMod = 0;


            //All modifiers from equipped items
            equippedItemsMod = gv.sf.CalcAttackBonusesNoAmmo(pc, isMainHand);

            //target is held bonus
            if (crt.isHeld())
            {
                targetHeldMod = 4;
                situationalModifier += 4;
                //gv.cc.addLogText("<font color='lime'>" + pc.name + " <font color='white'>attacks held creature: +4 att</font><BR>");
            }
 
            if (gv.sf.isMeleeAttack(pc)) //MELEE ONLY
            {
                //BAB and Effects total mod includes permanent Effects from Traits
                babEffectMod = gv.sf.CalcTotalEffectBABModifier(pc);
                
                //Attribute mod
                attributeMod = gv.sf.CalcPcMeleeAttackAttributeModifier(pc, isMainHand);
                
                //attack from behind modifier
                if (IsAttackFromBehind(pc, crt))
                {
                    fromBehindMod = gv.mod.attackFromBehindToHitModifier;
                    situationalModifier += gv.mod.attackFromBehindToHitModifier;
                    if (gv.mod.attackFromBehindToHitModifier > 0)
                    {
                        //gv.cc.addLogText("<font color='white'>Attack from behind: +" + gv.mod.attackFromBehindToHitModifier.ToString() + " to hit." + "</font><BR>");
                    }
                }

                //sneak attack bonus                
                if (pc.steathModeOn)
                {
                    if (pc.knownTraitsTags.Contains("sneakattack"))
                    {
                        //+1 for every 2 levels after level 1
                        int adding = ((pc.classLevel - 1) / 2) + 1;
                        sneakAttackMod = adding;
                        situationalModifier += adding;
                        //gv.cc.addLogText("<font color='lime'> sneak attack: +" + adding + " to hit</font><BR>");
                    }
                }

                //twoweaponfighting mod                
                if (hasWeaponInOffHand(pc))
                {
                    twoWeaponMod = gv.sf.CalcPcMeleeTwoWeaponModifier(pc, isMainHand);
                }

                //hard to kill mod            
                if (gv.sf.hasTrait(pc, "hardtokill"))
                {
                    hardToKillMod -= 2;
                    //gv.cc.addLogText("<font color='white'>" + "blinded by rage" + "</font><BR>");
                    //gv.cc.addLogText("<font color='white'>" + "-2 attack penalty" + "</font><BR>");
                }
            }
            else //RANGED ONLY
            {
                //Attribute mod
                attributeMod = (pc.dexterity - 10) / 2;
                
                //ammo used modifier                
                Item itm = gv.mod.getItemByResRefForInfo(pc.AmmoRefs.resref);
                if (itm != null)
                {
                    ammoMod = gv.mod.getItemByResRefForInfo(pc.AmmoRefs.resref).attackBonus;
                }
                
                //BAB and Effects total mod includes permanent Effects from Traits
                babEffectMod = gv.sf.CalcPcRangedAttackModifier(pc);
                
                //factor in penalty for adjacent enemies when using ranged weapon
                if (isAdjacentEnemy(pc))
                {
                    //if (gv.sf.hasTrait(pc, "pointblankshot"))
                    if (gv.sf.canNegateAdjacentAttackPenalty(pc))
                    {
                        //can ignore attack penalty due to PC having a pointblankshot type of trait or effect 
                    }
                    else
                    {
                        adjacentEnemyPenalty -= 4;
                        situationalModifier -= 4;
                        //gv.cc.addLogText("<font color='white'>" + "-4 ranged attack penalty" + "</font><BR>");
                        //gv.cc.addLogText("<font color='white'>" + "with enemies in melee range" + "</font><BR>");
                    }
                }
                
                //precise shot trait
                if (gv.sf.hasTrait(pc, "preciseshot2"))
                {
                    preciseShotAdder = 2;
                    //gv.cc.addLogText("<font color='lime'> PreciseShotL2: +2 to hit</font><BR>");
                }
                else if (gv.sf.hasTrait(pc, "preciseshot"))
                {
                    preciseShotAdder = 1;
                    //gv.cc.addLogText("<font color='lime'> PreciseShotL1: +1 to hit</font><BR>");
                }
            }

            if (situationalModifier != 0)
            {
                //gv.cc.addFloatyText(new Coordinate(pc.combatLocX, pc.combatLocY), "+" + situationalModifier + " att", "white");
            }

            int attackMod = equippedItemsMod + ammoMod + bab + babEffectMod + attributeMod + fromBehindMod + targetHeldMod 
                + adjacentEnemyPenalty + sneakAttackMod + twoWeaponMod + poorVisionMod + preciseShotAdder + hardToKillMod;
            
            return attackMod;
User avatar
slowdive
Site Admin
Posts: 485
Joined: Wed Jan 15, 2020 4:37 am

Re: Slowdive's Little Daily Blog

Post by slowdive »

I think I’ll add the adjacent ally AC bonus system to IB and make it a module setting so the author can choose to use it or not. The way it works is that a PC (or creature) gets a bonus to their AC for each ally that is in an adjacent square to them. This creates some benefit to staying close to each other and makes you think more about your location on the map. The down side is that AoE spells will take advantage of you if you group together so you will need to make a choice.

Thoughts?
User avatar
Dorateen
Posts: 262
Joined: Thu Jan 16, 2020 3:03 pm

Re: Slowdive's Little Daily Blog

Post by Dorateen »

slowdive wrote: Thu Oct 21, 2021 4:27 pm The way it works is that a PC (or creature) gets a bonus to their AC for each ally that is in an adjacent square to them.
I enjoy party mobility in tactical combat, so as a player I'm not likely to keep a character on adjacent ally square without reason. Having said that, if there is an AC bonus for doing so, I think it should be the result of some condition: like an aura of protection from a paladin, or a fighter who has the ability to block incoming attacks. I don't think by default, player characters should get the bonus for standing next to one another. But having it as a toggle in the settings is good so that builders can play around with the idea.
User avatar
slowdive
Site Admin
Posts: 485
Joined: Wed Jan 15, 2020 4:37 am

Re: Slowdive's Little Daily Blog

Post by slowdive »

I think the conditional based bonus makes sense. My thought was that when close together, you don't have to focus your defense on as many sides so you AC would be higher. Also, it adds additional strategy to position on the combat field and which enemy you attack (the middle one is more protected than the fringe enemies). I used to play a game called Lord's of Conquest ( https://www.c64-wiki.com/wiki/Lords_of_Conquest ) that used this mechanic and it made it feel more chess like (partially deterministic with combat location and random with attack and damage rolls). I finished adding the code into IB and have it set as a flag in the module's settings. I will set it to true in Hearkenwold for episode 5 just for show and then I'll turn it back to false for future episodes.

Next up I'll start adding the 3d view system in the toolset and then in the engine.
User avatar
Dorateen
Posts: 262
Joined: Thu Jan 16, 2020 3:03 pm

Re: Slowdive's Little Daily Blog

Post by Dorateen »

I definitely see the value in adding this additional strategic layer to positioning. And I think you mentioned it would apply to enemies, too? That should be interesting and it will be worth seeing the AC bonus setting in action.
Post Reply