PDA

View Full Version : Combat Tracker adjustments for a Custom Ruleset using CoreRPG



Blackfoot
January 17th, 2014, 05:31
So I'm about ready to bite off the big chew on my Champions Ruleset and make the changes to the Combat Tracker to handle character Speed. I'm going to explain it out here and hopefully some of you clever and knowledgeable guys will have some insights into how to implement it that I haven't thought of.

The way this works is that each character has a 'Speed' stat, this stat determines how many times a character acts each 'Turn'. A 'Turn' is broken up into 12 'Segments' so for example a character with a 2 Speed will act twice, once on Segment 6 and once on Segment 12. Within that Segment, initiative order is decided by Dexterity, and characters with the same Dexterity roll off against each other to determine who specifically goes first in a given Segment.

Sounds a bit complicated? Well it is.. which is why having a Combat Tracker keep it all straight will be a really nice thing.

Now I'm looking at the way this is done in 3.5 they are sorting 'initresult' as the primary, 'init' as the secondary, and 'name' as the tertiary sort.

I probably want 'Phase' (a name for the character's active segments) or 'Segment' to be the primary sort, dexterity to be the secondary, and the result of a d6 to be the tertiary. Since each character can act multiple times in a 'Turn' it seems like the tracker is going to need to resort after each character's turn selecting either the character with the next d6 roll, the next DEX, or moving on to the next 'Segment'.
I want there to be both 'Turn' Tracking (Round Tracking) and 'Segment' Tracking at the bottom of the Tracker window... and it would be nice to drop a break line across under the last player who can act on a given Segment. I probably do not need to 'show' the character's phase since it will be a line up of all the same numbers and they will be changing after each action.. a number at the bottom and a bar across should be good enough to show it... I want to show the 'dex' of the character.. although this number should be changeable since the character can 'delay' to a later dex value to act... I 'could' add the die roll on to the dex as a .1 to .6 that sort of thing the tracker already handles sorta... it would save me a box and might make the sort a little simpler.

There are other tricky bits like the character can 'ABORT' their next action to take a defensive maneuver, this would basically bump their 'next Segment' back one step in their speed table.

I built a phasedata table that looks like this:

phasedata = {
[1] = { 12 },
[2] = { 6, 12 },
[3] = { 4, 8, 12 },
[4] = { 3, 6, 9, 12 },
[5] = { 3, 5, 8, 10, 12 },
[6] = { 2, 4, 6, 8, 10, 12 },
[7] = { 2, 4, 6, 7, 9, 11, 12 },
[8] = { 2, 3, 5, 6, 8, 9, 11, 12 },
[9] = { 2, 3, 4, 6, 7, 8, 10, 11, 12 },
[10] = { 2, 3, 4, 5, 6, 8, 9, 10, 11, 12 },
[11] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 },
[12] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }
}
I probably did it wrong, but I'm just getting started on this piece.

Moon Wizard
January 17th, 2014, 21:04
Yeah, the current trackers all assume that everyone acts once per round, and it's just a matter of sorting.

I guess the first step is deciding what you want your interface to look like during play. My initial thoughts:
* Keep the entire combatant list visible in the tracker (to avoid confusion about who is currently in tracker)
* Highlight combatants who get to act this segment different than those that don't.
* Sort combatants who get to act this segment above those that don't, then sort by DEX.
* Change highlights and re-sort when segment field changes.
* Next actor button skips past characters that don't get to act, and then skips segments with no active characters
* When advancing by actor and you're on last combatant who gets to act this segment, then advance the segment.
* When advancing the segment and no combatants act that segment, advance the segment again.
* When segment advances past 12, advance the round.
* Watch for infinite loops when no actors in tracker (i.e. Don't advance round automatically, regardless of Stop on Round option, if CT empty)
* Add an advance segment button, separate than advance round. (Needed?)
* Skip the Delay/Abort for now.

Cheers,
JPG

Trenloe
January 17th, 2014, 22:22
I don't know anything about the Hero system, but I think I understand how the segments work from your description.

For the Star Wars: Edge of the Empire ruleset I split the combat tracker into 2 halves:

https://dl.dropboxusercontent.com/u/39085830/Screenshots/Fantasy%20Grounds/Star%20Wars%20EotE/Init%20Tracker.jpg

The bottom half contains all of the people (actors) taking part in the combat and the top half contains the initiative slots for the round. Actors records are moved up into the top half (init slot) when they decide to act.

Could a similar thing be done for this? Have the bottom half be all of the PCs and NPCs taking part in the combat and then the top half is all of the actors who can act in this segment - ordered as you outline above.

This is essentially the second star bullet point JPG lists above - instead of highlighting the combatants who take part in this segment move a copy of their record into the top half, clearing the records out at the end of the segment and adding in the records for the next segment.

Might that work?

Blacky
January 17th, 2014, 22:28
For HERO, I would (very) basically rename the current CT round as segment, and I would create a new variable round. Rotate the segment in base 12, increment the round at each full segment rotation.

This way you keep all the current sound mechanisms (actor after actor, etc.) going segment from segment, all you have to do is skip the ones not acting during this segment.

damned
January 18th, 2014, 01:45
no idea about the coding but are you sure that someone with a speed of 1 acts after every single other person has had as many as 12 turns?

Blackfoot
January 18th, 2014, 02:24
Speed is one of those things that is generally tightly controlled by the GM, they set house rules for what can and can't be taken as far as speed goes. If you have a game with a character that has a 12 speed... you don't have anybody who has a 1. A 12 speed would be a super-speedster who had invested a big part of their character into that. Most games I've played in had speed ranges of 2-4 or 3-7 depending on the power level of the heroes. 'Normals' start with a 2.
A character who acts a lot but can't really do much with their actions is not atypical with high speed characters.

Blackfoot
January 18th, 2014, 05:52
OI. I got this working rather nicely, cept for one problem. When you follow yourself..

function onTurnEnd(nodeEntry)
if not nodeEntry then
return;
end

-- Find Next Phase
local nPhase = 0;
local nNextPhase = 0;
local nCurrPhase = DB.getValue(nodeEntry, "phase", 0);
local nSpeedVal = DB.getValue(nodeEntry, "speed", 0);
local rActor = ActorManager.getActor("ct", nodeEntry);
local nEffectVal, nEffects = EffectManager.getEffectsBonus(rActor, "SPD", true);
nSpeedVal = nSpeedVal + nEffectVal;
local aPhases = DataCommon.phasedata[nSpeedVal];
for i, v in ipairs(aPhases) do
if nPhase == 1 or nCurrPhase == 12 then
nNextPhase = v;
nPhase = 0;
nCurrPhase = 0;
end
if nCurrPhase < v and nNextPhase == 0 then
nNextPhase = v;
end
if v == nCurrPhase then
nPhase = 1;
end
end
DB.setValue(nodeEntry, "phase", "number", nNextPhase);
end
Whenever you follow yourself it doesn't realize it should not move on to the next guy and leaves you behind... hrm. dangit.

Blackfoot
January 20th, 2014, 18:32
Hmm.. I was thinking I could use the code for the 'immediate' flag to deal with 'abort' actions.
Basically the flag gets clicked when the character takes a defensive action and 'abort's their next action.. then when the tracker gets to the character's phase it advances their phase and moves immediately to the next actor.
I've got some of this working already.. but I need the call to advance to the next actor.
EDIT: Found it.. CombatManager.nextActor()... duh.

Also ... I think I want this flag to be flippable from the client side... so they can take their 'abort' and it announces it to the chat window and toggles the flag. So I need to set it up so the flag is only viewable by the owner of the character on the CT.

Blackfoot
January 21st, 2014, 07:23
Minor thing.. but really the '[TURN]' and '[ROUND]' notices to the chat window would be better represented with variable 'strings'.. this would facilitate language and rules terminology changes when inheriting CoreRPG.
These are handled in the CombatManager and not part of a Customizable function.

Blackfoot
January 21st, 2014, 17:55
Question: How does it work when you click on the Character in the Tracker to change who is currently active in the CT? I'm having trouble finding the code that makes this happen.
I'm thinking that a call to this function might resolve my issue with a player who acts again immediately after his action finishes.

Trenloe
January 21st, 2014, 18:00
Question: How does it work when you click on the Character in the Tracker to change who is currently active in the CT? I'm having trouble finding the code that makes this happen.
I'm thinking that a call to this function might resolve my issue with a player who acts again immediately after his action finishes.
The button is "button_ctentry_active" in ct_host.xml
This is defined in template_ct.xml and uses the ct/scripts/ct_active.lua script file.
In this file you have the onClickRelease() function:

function onClickRelease(button, x, y)
if (getValue() == 0) and User.isHost() then
CombatManager.requestActivation(window.getDatabase Node(), true);
end
return true;
end
There you go - CombatManager.requestActivation() is the function you're looking for.

Blackfoot
January 21st, 2014, 18:06
There you go - CombatManager.requestActivation() is the function you're looking for.
Thanks... I clearly wasn't looking at the right thing. :)
This should help a lot.

EDIT: This didn't end up working but I think I may have gotten it to work. My issue now is with the Bell ringing for the next player.

Blackfoot
January 22nd, 2014, 05:30
Yeah.. I'm pretty much back to the drawing board on this one.
I tried saving a link to the node off and then calling requestActivation(node).. but it ends up displaying both characters and ringing the bells for both.. and ticking the timer on effects.. (although this is another issue I seem to have that needs tracking down)
I'm guessing at this point I'm going to need to build my own nextActor function at this point to work around CombatManager... I wanted to avoid this but I don't see another way.

Blackfoot
January 22nd, 2014, 19:18
Still slugging it out with this thing...
I tried setting it up so that it would automatically shift the focus to the previous record in the tracker in situations where the problem occurred... but the problem there is that often, when the player follows himself, he is the first actor in the tracker. I am now considering setting up a 'dummy' actor in the tracker that would become the focus briefly in these situations. It does follow somewhat with my original design which involved setting up some sort of separation between the actors in the 'current' segment and the rest of the actors... I might want to set up a 'last actor in the segment' as well... the create some unique graphics to represent these dummies as bars.

I set up 2 actors with 12 speeds one with a 100 DEX and the other with 0 DEX

Wow... ok that seems to solve the problem.. now to make it pretty.

Trenloe
January 22nd, 2014, 19:27
The first portion of CombatManager.requestActivation de-activates all entries in the combat tracker before activating the specific entry requested:

function requestActivation(nodeEntry, bSkipBell)
-- De-activate all other entries
for _, vChild in pairs(DB.getChildren(CT_LIST)) do
DB.setValue(vChild, "active", "number", 0);
end
...

Although this is be ran by any call to CombatManager.requestActivation you may want to try running this at the end of the segment before doing any activation for the next segment/round?

Blackfoot
January 22nd, 2014, 20:02
Although this is be ran by any call to CombatManager.requestActivation you may want to try running this at the end of the segment before doing any activation for the next segment/round?
The way the tracker is working right now, segments are basically fluid running directly from one to the next with the sort handling the change... I do have a check that updates a Segment box at the bottom of the tracker but this happens in the middle of the 'CombatManager.nextActor' function so at that point the order of actors is already set. I am treating a 'Turn' as a 'Round' (in 3.5 terms) and the characters shuffle up and down the tracker several times each 'Round' depending on their speed. It's all working great just using the normal sort functions.. the only issue comes when you get to go twice in a row... then it skips your second action and moves right along to the next guy. The dummy bar solution works for this because the next guy at the end of each segment is always the bar... all I need to do is set up an automatic skip over for the dummy and I should be in good shape.. I think. (I hope)

Blackfoot
January 22nd, 2014, 20:30
Wow.. ok that was a LOT simpler solution than I was working toward.
I added: DB.setValue(vChild, "active", "number", 0);
just before calling nextActor or requestActivation... and it did the trick... now to remove all the extra Faction code I was adding for my bars :)
Thanks Trenloe.

Trenloe
January 22nd, 2014, 20:33
Cool - glad it worked OK. :)