Skip to content

Commit

Permalink
Merge pull request #64 from lonevvolf/book-28
Browse files Browse the repository at this point in the history
Book 28
  • Loading branch information
cracrayol authored Sep 13, 2024
2 parents 728d512 + 54b28c7 commit e855f54
Show file tree
Hide file tree
Showing 35 changed files with 2,042 additions and 62 deletions.
1 change: 1 addition & 0 deletions doc/README-mechanics.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ The saveInventoryState optional property "objectsType" identifies the objects to
* **all**: The backpack content, the backpack itself, special items, meals and money (This is the default value)
* **weaponlike**: Weapons and weapon-like special items
* **bow**: Bow weapons
* **kaiweapon**: Kai Weapon (New Order)
* **allobjects**: The backpack content, special items and meals

The restoreInventoryState optional property "restoreWeapons" identifies if the Weapons, and weapon Special Items should be recovered. Default value is true. If it's false, weapons are not returned, and they can be recovered later with the same restore point.
Expand Down
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@typescript-eslint/parser": "^8.3.0",
"eslint": "^9.9.1",
"fs-extra": "^10.1.0",
"he": "^1.2.0",
"jest": "^29.7.0",
"jest-ctrf-json-reporter": "^0.0.9",
"jest-environment-jsdom": "^29.7.0",
Expand All @@ -27,6 +28,7 @@
"preprocess": "^3.2.0",
"selenium-webdriver": "^4.1.2",
"simple-git": "^3.7.1",
"striptags": "^3.2.0",
"terser-webpack-plugin": "^5.3.10",
"ts-jest": "^29.2.5",
"ts-loader": "^9.3.0",
Expand Down
2 changes: 1 addition & 1 deletion src/ts/controller/actionChartController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ export const actionChartController = {
*/
getBonusesText(bonuses: Bonus[]) {
const txt = [];
for (const bonus of bonuses) {
for (const bonus of bonuses.filter((b) => !b.enemy)) {
let txtInc = bonus.increment.toString();
if (bonus.increment > 0) {
txtInc = "+" + txtInc;
Expand Down
5 changes: 2 additions & 3 deletions src/ts/controller/gameRulesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,12 @@ export const gameRulesController = {
},

appendSection( sectionId: string ) {

const section = new Section( state.book , sectionId , state.mechanics );
const renderer = new SectionRenderer( section );

// Add a target anchor
let html = '<a id="' + sectionId + '"></a>';
html += "<h2>" + section.getTitleHtml() + "</h2>";
let html = $("<a>").prop("id", sectionId)[0].outerHTML;
html += $("<h2>").text(section.getTitleHtml())[0].outerHTML;
html += renderer.renderSection();

$("#rules-content").append( html );
Expand Down
23 changes: 18 additions & 5 deletions src/ts/controller/mechanics/combatMechanics.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { state, mechanicsEngine, Combat, template, SpecialObjectsUse, CombatTurn, GndDiscipline, translations, BookSeriesId, NewOrderDiscipline } from "../..";
import striptags = require('striptags');

/**
* Combats mechanics
Expand Down Expand Up @@ -297,7 +298,7 @@ export class CombatMechanics {
* @param turn The turn to render
*/
private static renderCombatTurn( $combatTableBody: JQuery<HTMLElement> , turn: CombatTurn ) {
$combatTableBody.append(`<tr><td class="hidden-xs">${turn.turnNumber}</td><td>${turn.randomValue}</td><td>${turn.getPlayerLossText()}</td><td>${turn.getEnemyLossText()}</td></tr>`);
$combatTableBody.append(`<tr><td class="hidden-xs">${striptags(turn.turnNumber.toFixed())}</td><td>${striptags(turn.randomValue.toFixed())}</td><td>${striptags(turn.getPlayerLossText())}</td><td>${striptags(turn.getEnemyLossText())}</td></tr>`);
}

/**
Expand Down Expand Up @@ -564,18 +565,20 @@ export class CombatMechanics {
const combat = sectionState.combats[ combatIndex ];

const finalCSPlayer = combat.getCurrentCombatSkill();
let finalCSEnemy = combat.getCurrentEnemyCombatSkill();

// Player CS for this combat:
let csPlayer: string = state.actionChart.combatSkill.toString();
let csEnemy: string = combat.combatSkill.toString();
const bonuses = combat.getCSBonuses();
for ( const bonus of bonuses ) {
for ( const bonus of bonuses.filter((b) => !b.enemy) ) {
csPlayer += " ";
if ( bonus.increment >= 0 ) {
csPlayer += "+";
}
csPlayer += bonus.increment.toString() + " (" + bonus.concept + ")";
}
if ( bonuses.length > 0 ) {
if ( bonuses.filter((b) => !b.enemy).length > 0 ) {
csPlayer += " = " + finalCSPlayer.toString();
}
$("#game-ratioplayer").text( csPlayer );
Expand All @@ -584,11 +587,21 @@ export class CombatMechanics {
}

// Enemy info:
for ( const bonus of bonuses.filter((b) => b.enemy) ) {
csEnemy += " ";
if ( bonus.increment >= 0 ) {
csEnemy += "+";
}
csEnemy += bonus.increment.toString() + " (" + bonus.concept + ")";
}
if ( bonuses.filter((b) => b.enemy).length > 0 ) {
csEnemy += " = " + finalCSEnemy.toString();
}
$("#game-ratioenemyname").html( combat.enemy );
$("#game-ratioenemy").text( combat.combatSkill );
$("#game-ratioenemy").text( csEnemy );

// Combat ratio result:
$("#game-ratioresult").text( `${finalCSPlayer} - ${combat.combatSkill} = ${( finalCSPlayer - combat.combatSkill )}` );
$("#game-ratioresult").text( `${finalCSPlayer} - ${finalCSEnemy} = ${( finalCSPlayer - finalCSEnemy )}` );

// Show dialog
$("#game-ratiodetails").modal();
Expand Down
11 changes: 9 additions & 2 deletions src/ts/controller/mechanics/mechanicsEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { views, translations, Section, gameView, state, CombatMechanics, randomM
App, ExpressionEvaluator, numberPickerMechanics, disciplinePickerMechanics, kaiWeaponPickerMechanics, SkillsSetup, KaiNameSetup, SetupDisciplines, EquipmentSectionMechanics, actionChartController,
CurrencyName, LoreCircle, BookSeriesId, MealMechanics, ActionChartItem, InventoryState, actionChartView, template, Book,
GrandMasterUpgrade, kaimonasteryController, book2sect238, book2sect308, book3sect88, book6sect26, book6sect284,
book6sect340, book9sect91, book19sect304, ObjectsTable, ObjectsTableType, setupController, KaiDiscipline, MgnDiscipline,
book6sect340, book9sect91, book19sect304, book28sect71, book28sect192, ObjectsTable, ObjectsTableType, setupController, KaiDiscipline, MgnDiscipline,
GndDiscipline, projectAon, DebugMode } from "../..";

/**
Expand Down Expand Up @@ -101,7 +101,7 @@ export const mechanicsEngine = {
run(section: Section) {

// Defaults:
gameView.enableNextLink(true);
gameView.enableNextLink(section.sectionId !== state.mechanics.getLastSectionId());
mechanicsEngine.onAfterCombatsRule = null;
mechanicsEngine.onEludeCombatsRule = null;
mechanicsEngine.onInventoryEventRule = null;
Expand Down Expand Up @@ -1765,6 +1765,13 @@ export const mechanicsEngine = {
book19sect304.run();
},

book28sect71() {
book28sect71.run();
},

book28sect192() {
book28sect192.run();
},
/************************************************************/
/**************** RULES HELPERS *****************************/
/************************************************************/
Expand Down
63 changes: 63 additions & 0 deletions src/ts/controller/mechanics/specialSections/book28sect192.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { state, Combat, InventoryState, actionChartController, mechanicsEngine, gameController, ObjectsTableType, ObjectsTable, Mechanics } from "../../..";

/**
* Generate trader with funny deals
* This has an issue:
* If you buy an item, then drop a special item, then drop the purchased item, then pick up the special item, the already purchased item will cost money
*/
export const book28sect192 = {

run() {
const sectionState = state.sectionStates.getSectionState();
var itemPrice = 4;
var refresh = false;
const items = ["klorvapotion", "sabitoroot", "anduiflask"];

// If there is one item left with a price of 4, reduce it to 2 (total cost of 3 items will be 10)
if (sectionState.objects.filter((o) => o.price > 0).length === 1) {
itemPrice = 2;
}

// If there is a Special Item on the section, make the items free
if (sectionState.getCntSectionObjects("special")) {
itemPrice = 0;
}

// If the price has changed, update the objects and mark for refresh
if (sectionState.objects && sectionState.objects.length && sectionState.objects[0].price != itemPrice) {
items.forEach((itemToUpdate) => {
if (sectionState.getSectionObjects().find((item) => item.id === itemToUpdate)) {
let rule = $(`<object objectId="${itemToUpdate}" />`);
delete sectionState.executedRules[ Mechanics.getRuleSelector(rule[0]) ];
sectionState.removeObjectFromSection(itemToUpdate, -1);
refresh = true;
}
});
}

// Add the objects to the available objects on the section
items.forEach((itemToUpdate) => {
let rule = $(`<object objectId="${itemToUpdate}" />`);
// Do not execute the rule twice:
if (!sectionState.ruleHasBeenExecuted(rule[0])) {
sectionState.addObjectToSection(itemToUpdate, itemPrice);
sectionState.markRuleAsExecuted(rule[0]);
}
});

// If there is a Special Item on the section, prevent pickup unless all the sale items are still there
if (sectionState.objects && sectionState.objects.length
&& sectionState.getCntSectionObjects("special")
&& !(sectionState.objects.find((o) => o.id == "klorvapotion")
&& sectionState.objects.find((o) => o.id == "sabitoroot")
&& sectionState.objects.find((o) => o.id == "anduiflask"))) {
const itemToDisable = sectionState.getSectionObjects("special")[0].id;
$(`a[data-objectid='${itemToDisable}']`).attr('disabled', 'disabled');
}

if (refresh) {
gameController.loadSection(state.sectionStates.currentSection, false,
window.pageYOffset);
}
}
};
77 changes: 77 additions & 0 deletions src/ts/controller/mechanics/specialSections/book28sect71.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { state, Combat, InventoryState, actionChartController } from "../../..";

/**
* Generate combat against own Kai Weapon
*/
export const book28sect71 = {

run() {
// Get stored Kai Weapon
const restorePoint = "lostKaiWeapon";
const inventoryStateObject: any = state.sectionStates.otherStates[restorePoint];
const inventoryState = InventoryState.fromObject(inventoryStateObject);
const kaiWeaponItem = inventoryState.specialItems[0];
const sectionState = state.sectionStates.getSectionState();

// If the combat has already been added
if (sectionState.combats.length) {
return;
}

const pageCombat = $(".combat");
var defaultCS = pageCombat.contents().filter(function() {
return this.nodeType == 3;
}).first().text();
var defaultEP = pageCombat.contents().filter(function() {
return this.nodeType == 3;
}).last().text();

var extractedCS = defaultCS.replace(/[^0-9]/gi, ''); // Replace everything that is not a number with nothing
var extractedEP = defaultEP.replace(/[^0-9]/gi, ''); // Replace everything that is not a number with nothing
var enemyCS = parseInt(extractedCS, 10);
var enemyEP = parseInt(extractedEP, 10);

// Adjust enemy CS by 5 less any damage to the weapon
if (kaiWeaponItem) {
enemyCS += 5 + kaiWeaponItem.damage;
extractedCS += ` +${5 + kaiWeaponItem.damage} CS Kai Weapon Bonus`;

// Adjust enemy CS for any bonuses
if (kaiWeaponItem.id === "illuminatus") {
enemyCS += 2;
extractedCS += ` +2 CS Illuminatus`;
} else if (kaiWeaponItem.id === "valiance" &&
(state.actionChart.hasDiscipline("alchemy") || state.actionChart.hasDiscipline("magi"))) {
enemyCS += 3;
extractedCS += ` +3 CS Valiance`;
} else if (kaiWeaponItem.id === "kaistar") {
enemyCS += 2;
extractedCS += ` +2 CS Kaistar`;
}
}

// Remove the existing combat from UI and state, to be replaced with a new one
$(".combat").remove();
state.sectionStates.getSectionState().combats[0].combatSkill = enemyCS;

$('#game-section > p.choice').before(
`<div class="combat well">
<b>Tomb Robbers (with Kai Weapon)</b>
<br>
<span class="attribute">
COMBAT SKILL
</span>
: ${extractedCS} &nbsp;&nbsp;
<span class="attribute">
ENDURANCE
</span>:
<span class="enemy-current-endurance">
${enemyEP}
</span>
/ ${enemyEP}
</div>`);

// Add combat to the section
state.sectionStates.getSectionState().combats.push(new Combat("Tomb Robbers (with Kai Weapon)", enemyCS, enemyEP));
}
};
3 changes: 2 additions & 1 deletion src/ts/controller/testsController.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { views, BookValidator, setupController, state, Section, SectionRenderer, randomTable, projectAon, mechanicsEngine } from "..";
import striptags = require('striptags');

/**
* Application tests
Expand Down Expand Up @@ -161,7 +162,7 @@ export class testsController {
}

private static addLog( textLine: string ) {
$("#tests-log").append(textLine + "</br>");
$("#tests-log").append(striptags(textLine) + "</br>");
}

private static addError( textLine: string , exception: any = null ) {
Expand Down
2 changes: 2 additions & 0 deletions src/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export * from "./controller/mechanics/specialSections/book6sect26";
export * from "./controller/mechanics/specialSections/book6sect340";
export * from "./controller/mechanics/specialSections/book9sect91";
export * from "./controller/mechanics/specialSections/book19sect304";
export * from "./controller/mechanics/specialSections/book28sect71";
export * from "./controller/mechanics/specialSections/book28sect192";
export * from "./controller/mechanics/randomMechanics";
export * from "./controller/mechanics/equipmentSectionMechanics";
export * from "./controller/mechanics/numberPickerMechanics";
Expand Down
Loading

0 comments on commit e855f54

Please sign in to comment.