Initiative from PHASE OK

This commit is contained in:
sladecraven 2021-02-04 08:38:59 +01:00
parent d248411e90
commit 63e552cc6a
6 changed files with 71 additions and 30 deletions

View File

@ -10,21 +10,57 @@ export class SoSCombat extends Combat {
async nextRound() {
console.log("NEXT ROUND !!!!");
if ( game.user.isGM ) {
ChatMessage.create( { content: `New round !! Click on the button below to declare your actions for round ${this.round} !<br>
<a class='chat-card-button' id='button-declare-actions' data-combat-id='${this._id} data-round='${this.round}'>Declare actions</a>`,
whisper: game.users.map(user => user.data._id) } );
if ( game.user.isGM ) {
for( let combatant of this.combatants) {
let uniq = randomID(16);
if ( combatant.players[0]) {
// A player controls this combatant -> message !
ChatMessage.create( { content: `New round ! Click on the button below to declare the actions of ${combatant.actor.data.name} for round ${this.round} !<br>
<a class='chat-card-button' id='button-declare-actions' data-uniq-id='${uniq}' data-combatant-id='${combatant._id}' data-combat-id='${this._id}' data-round='${this.round}'>Declare actions</a>`,
whisper: [ combatant.players[0].data._id] } );
} else {
ChatMessage.create( { content: `New round ! Click on the button below to declare the actions of ${combatant.actor.data.name} for round ${this.round} !<br>
<a class='chat-card-button' id='button-declare-actions' data-uniq-id='${uniq}' data-combatant-id='${combatant._id}' data-combat-id='${this._id}' data-round='${this.round}'>Declare actions</a>`,
whisper: [ ChatMessage.getWhisperRecipients("GM") ] } );
}
}
}
super.nextRound();
}
/* -------------------------------------------- */
getPhaseRank( actionConf) {
for (let i=2; i>=0; i--) {
let action = actionConf.phaseArray[i];
if (action.name != "No Action") {
console.log("Init is : ", i+1);
return i+1;
}
}
return 0;
}
/* -------------------------------------------- */
setupActorActions(actionConf) {
console.log("Setting combat for phase : ", actionConf);
if ( !this.phaseSetup) this.phaseSetup = []; // Opportunistic init
if ( !this.phaseSetup[this.round] ) this.phaseSetup[this.round] = {}; // Bis
// Keep track
this.phaseSetup[this.round][actionConf.userId] = actionConf;
this.phaseSetup[this.round][actionConf.combatantId] = actionConf;
console.log( this.combatants);
let combatant = this.combatants.find( comb => comb._id == actionConf.combatantId);
this.setInitiative( actionConf.combatantId, this.getPhaseRank( actionConf ) );
let actionsDone = true
for( let combatant of this.combatants) {
if ( !combatant.initiative ) actionsDone = false;
}
if ( actionsDone ) {
ChatMessage.create( { content: `Action phase has been completed ! Now proceeding with actions.`,
whisper: [ ChatMessage.getWhisperRecipients("GM") ] } );
}
}
}

View File

@ -4,12 +4,14 @@ import { SoSUtility } from "./sos-utility.js";
export class SoSDialogCombatActions extends Dialog {
/* -------------------------------------------- */
static async create( combatId, round ) {
static async create( combatId, combatantId, round, uniqId ) {
let combatActions = {
actionsList: await SoSUtility.loadCompendium( 'foundryvtt-shadows-over-sol.combat-actions' ),
actionPoints: SoSUtility.fillRange(0, 6),
combatId: combatId,
combatantId: combatantId,
uniqId: uniqId,
round: round
}
for ( let i=0; i<combatActions.actionsList.length; i++) {
@ -54,13 +56,26 @@ export class SoSDialogCombatActions extends Dialog {
let action2 = duplicate(this.combatActions.actionsList[action2Index]._id);
let action1Index = $('#action1').val();
let action1 = duplicate(this.combatActions.actionsList[action1Index]._id);
game.socket.emit("system.foundryvtt-reve-de-dragon", {
name: "msg_declare_actions", data: {
userId: game.userId,
phaseArray: [ action1, action2, action3],
remainingAP: ap
} } );
let msgdata = {
combatId: this.combatActions.combatId,
combatantId: this.combatActions.combatantId,
uniqId: this.combatActions.uniqId,
userId: game.userId,
phaseArray: [ action1, action2, action3],
remainingAP: ap
}
if ( game.user.isGM ) {
let combat = game.combats.get( this.combatActions.combatId ); // Get the associated combat
combat.setupActorActions( msgdata );
} else {
game.socket.emit("system.foundryvtt-reve-de-dragon", {
name: "msg_declare_actions", data: msgdata } );
}
// Delete message !
const toDelete = game.messages.filter(it => it.data.content.includes( this.combatActions.uniqId ));
toDelete.forEach(it => it.delete());
} else {
ui.notifications.warn("Action Points are below 0 ! Please check your phases !");
}
@ -68,6 +83,7 @@ export class SoSDialogCombatActions extends Dialog {
/* -------------------------------------------- */
validateActions( html ) {
}
/* -------------------------------------------- */

View File

@ -18,16 +18,6 @@ import { SoSCombat } from "./sos-combat.js";
/* Foundry VTT Initialization */
/* -------------------------------------------- */
/************************************************************************************/
const _patch_initiative = () => {
Combat.prototype.rollInitiative = async function (
ids,
formula = undefined,
messageOptions = {}
) {
}
}
/************************************************************************************/
Hooks.once("init", async function () {
console.log(`Initializing Shadows over Sol System`);
@ -40,7 +30,7 @@ Hooks.once("init", async function () {
/* -------------------------------------------- */
// Set an initiative formula for the system
CONFIG.Combat.initiative = {
formula: "1+(1d6/10)",
formula: "1d3",
decimals: 2
};
@ -68,9 +58,6 @@ Hooks.once("init", async function () {
SoSUtility.registerChatCallbacks(html);
});
// Patch the initiative formula
_patch_initiative();
});
/* -------------------------------------------- */

View File

@ -64,8 +64,10 @@ import { SoSDialogCombatActions } from "./sos-dialog-combat-actions.js";
static async openDeclareActions( event) {
event.preventDefault();
let round = event.currentTarget.attributes['data-round'].value;
let combatantId = event.currentTarget.attributes['data-combatant-id'].value;
let combatId = event.currentTarget.attributes['data-combat-id'].value;
let d = await SoSDialogCombatActions.create( combatId, round );
let uniqId = event.currentTarget.attributes['data-uniq-id'].value;
let d = await SoSDialogCombatActions.create( combatId, combatantId, round, uniqId );
d.render(true);
}

View File

@ -10,6 +10,7 @@
{"name":"First Aid","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"interact","minap":1,"description":"<p>To apply first aid in combat, the healer should make a Dex/medic-10 flip. The action benefits from having the appropriate tools (see page 111). On a success, she may remove the patient&rsquo;s Bleeding consequence. A medic may not remove Wound consequences in the span of a combat round unless she has gear specifically capable of this (healing wounds normally takes 10 minutes; see page 119).</p>\n<p>Performing first aid in combat requires at least 1 AP or at least 2 AP if performing it on oneself.</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_health.svg","effects":[],"_id":"NVzQN62rV05WYKSD"}
{"name":"Grapple","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"attack","minap":1,"description":"<p>Sometimes the best tactic is to grab one&rsquo;s&nbsp;opponent with one&rsquo;s bare hands and grapple&nbsp;with her. To do this, the attacker must have&nbsp;a free hand. Should she not have a free hand&nbsp;available, she may immediately drop whatever&nbsp;she is holding, thereby gaining one or more&nbsp;free hands to grapple with.&nbsp;</p>\n<p>Characters in a grapple may not take&nbsp;move actions until the grapple is broken.&nbsp;&nbsp;Breaking a grapple is free for the initiator&nbsp;of the grapple, but for other characters, it&nbsp;requires a successful Str/melee vs. Defense&nbsp;flip&mdash;an attack action. This attack does not&nbsp;deal damage and is made at a -4 penalty.&nbsp;</p>\n<p>While in a grapple, all actions that do not&nbsp;solely target the grappling opponent are at a -4 penalty. Additionally, as an attack action, a grappler may make Str/melee vs. End flip to&nbsp;choke her target. On a success, this increases&nbsp;the target&rsquo;s Fatigue consequence a severity.&nbsp;If she&rsquo;s already at Fatigue (critical), it instead&nbsp;renders her unconscious.</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_grapple.svg","effects":[],"_id":"Q8kTBgxjEV3jMCF4"}
{"name":"Trick","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"interact","minap":1,"description":"<p>Sometime it&rsquo;s possible to trick an enemy,&nbsp;granting an opening that can be exploited in&nbsp;combat. Such tricks are usually high risk, high&nbsp;&nbsp;reward actions, and they always leave the foe all&nbsp;the wiser against similar future actions. Tricks&nbsp;will usually be opposed actions, although the&nbsp;exact stats and skills will vary depending on&nbsp;the nature of the trick. For example, spraying&nbsp;congealed blood in a foe&rsquo;s face might be a Dex/athletics vs. Spd flip, while faking a punch to&nbsp;leave an opening might be a Chr/melee vs. Int&nbsp;flip. Regardless of the nature of the trick, on a&nbsp;success, the foe&rsquo;s Dazed consequence increases a&nbsp; severity. With Mag 5+ it increases by two severities. On the other hand, should the trick fail,&nbsp;the trickster increases her Dazed consequence a&nbsp;severity or two severities if she failed by Mag 5+.</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_trick.svg","effects":[],"_id":"TBgzXqY7gMjCV6gm"}
{"name":"No Action","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"other","minap":0,"description":0},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_none.svg","effects":[],"_id":"bqSieyyOLSY8tU2U"}
{"name":"Coordinate","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"interact","minap":1,"description":"<p>There&rsquo;s a reason that small tactical units train together, have their own comm channels and have a clear command structure. Groups&nbsp;of people fight better when coordinated. In combat, a character may take an Int/persuade-10 flip to try to coordinate her allies.</p>\n<p>A character may coordinate up to a number of&nbsp;allies equal to her intelligence. This requires the&nbsp;ability to clearly communicate with the coordinated allies, and benefits&nbsp; from appropriate&nbsp;tools, such as linked comms (see page 194).&nbsp;</p>\n<p>A character may not coordinate herself. On&nbsp;a success, all coordinated allies increase their&nbsp;Bolstered consequence by a severity. With 5+&nbsp;Mag, they increase it two severities.</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_coordinate.svg","effects":[],"_id":"dES68v89c6rJuijs"}
{"name":"Aim","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"concentrate","minap":1,"description":"<p>With an aim action, a character may take a moment to apply some extra focus and attention when lining up an attack. When this action is taken, the character must specify the target, who must be visible. Every AP spent on the aim provides a +2 bonus to her next attack on the target to a maximum bonus equal to the character&rsquo;s Perception. This bonus can carry over round to round, but the character&rsquo;s aim is broken if she takes any action other than to continue to aim at the target or if she takes a dodge or a zone of control reaction against a different target.</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_aim.svg","effects":[],"_id":"ePuCC1vQfMFSnSlj"}
{"name":"Disarm","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"attack","minap":1,"description":"<p>Make an attack at a -4 penalty. This attack forces the target to drop her weapon, usually because the attack hit her arm or weapon. Once&nbsp;dropped, the weapon lands on the ground a meter or two away from the target. With a disarm, the&nbsp;attacker may choose not to deal the usual damage.</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_disarm.svg","effects":[],"_id":"jtfMVasuf8c6B7pd"}
@ -17,4 +18,3 @@
{"name":"Taking Cover","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"move","minap":1,"description":"<p>Sometimes a basic move or a change in posture will be enough to gain a character&nbsp;the Cover or Concealment consequences. To&nbsp;make the most of these, however, the character&nbsp;will need to make a take cover action. There&nbsp;is a difference between &ldquo;taking cover&rdquo; and simply having cover.&nbsp;Think of it like this: if Monique is being&nbsp;fired upon and runs to where a stack of barrels&nbsp;is between her and her attacker, she has cover&nbsp;from the attacks. At the same time, if she wants to shoot back, the barrels are in her way as well. She has cover, but she hasn&rsquo;t &ldquo;taken cover&rdquo; to make the most of it.</p>\n<p>When a character takes cover, she needs&nbsp;to have moved immediately next to the object providing her with the cover consequence. She&nbsp;then performs the take cover action, setting&nbsp;herself up so that the cover does not hinder&nbsp;her attacks but still provides her with protection against the attacks of others. Without this,&nbsp;the cover&rsquo;s bonus to Defense applies both to&nbsp;incoming and outgoing attacks.</p>\n<p>&nbsp;</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_cover.svg","effects":[],"_id":"pwq6CB24QhNkrt1s"}
{"name":"Posture","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"move","minap":1,"description":"<p>By default, characters are assumed to be standing. There are times, however, when a character might want to kneel, crouch, sit or lay down. Changing between any of these postures is a move action, and one change in posture may be tacked on for free to another move action, such as a basic move or taking cover. If performed by itself, changing posture costs the usual amount of AP for the phase.</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_posture.svg","effects":[],"_id":"tF8mIKv0zi2HLv9B"}
{"name":"Drawing/Reloading","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"interact","minap":1,"description":"<p>Drawing a weapon or reloading one is a simple interact action that involves taking a weapon out or putting ammunition into one. This costs at least 1 AP if the weapon or magazine was in a holster or other easy-to-access position. It costs at least 2 AP if it was harder to reach, such as stowed at the top of a pack or tucked inside one&rsquo;s boot. Some weapons may have longer reload times, requiring more AP. This will be noted in the weapon&rsquo;s properties.</p>\n<p>&nbsp;</p>\n<p>&nbsp;</p>"},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_reload.svg","effects":[],"_id":"uSQw858IiBrWkeSj"}
{"name":"No Action","permission":{"default":0,"pJLHbu8WlBVyfXG4":3},"type":"action","data":{"type":"other","minap":0,"description":0},"flags":{},"img":"systems/foundryvtt-shadows-over-sol/img/icons/action_none.svg","effects":[],"_id":"bqSieyyOLSY8tU2U"}

View File

@ -2,7 +2,7 @@
"name": "foundryvtt-shadows-over-sol",
"title": "Shadows over Sol",
"description": "Shadows over Sol for FoundryVTT",
"version": "0.0.12",
"version": "0.0.13",
"manifestPlusVersion": "1.0.0",
"minimumCoreVersion": "0.7.5",
"compatibleCoreVersion": "0.7.9",