Skip to content

Commit

Permalink
Merge pull request #521 from hanshino/feat/star
Browse files Browse the repository at this point in the history
Add character rankup feature and adjust rankup cost
  • Loading branch information
hanshino authored Sep 12, 2024
2 parents a922326 + 9d96b54 commit fc69a6c
Show file tree
Hide file tree
Showing 17 changed files with 473 additions and 1,251 deletions.
21 changes: 20 additions & 1 deletion app/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,26 @@
"princess": {
"character": {
"full_image": "https://chieru.hanshino.dev/assets/units/full/%s.png",
"head_image": "https://chieru.hanshino.dev/assets/units/head/%s.png"
"head_image": "https://chieru.hanshino.dev/assets/units/head/%s.png",
"rank_up_cost_rate": 100,
"rank_up_cost": [
{
"rank": 1,
"cost": 30
},
{
"rank": 2,
"cost": 50
},
{
"rank": 3,
"cost": 100
},
{
"rank": 4,
"cost": 120
}
]
}
},
"gamble": {
Expand Down
12 changes: 12 additions & 0 deletions app/locales/zh_tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,18 @@
"thief_start_job_mission": "已開始進行盜賊的轉職任務,限時 10 分鐘",
"thief_start_job_mission_help": "那麼找出三個有價值的錢包吧~",
"change_job_level_limit": "至少要到達 30 等才能進行轉職"
},
"character": {
"not_found": "找不到角色",
"multiple_found": "找到多個角色,請輸入更多資訊以縮小搜尋範圍",
"not_enough_money": "女神石不足,無法進行此動作",
"rank_up_confirm": "確定要花費 *{{ cost }}* 將 *{{ name }}* 升級到 *{{ rank }}* 星嗎?\n請改輸入 `!升星 {{ name }}`\n手機用戶可直接點擊上面按鈕",
"rank_up_success": "成功將 *{{ name }}* 升級到 *{{ rank }}* 星",
"rank_max": "已達到最高星數",
"rank_up_manual": "請輸入 `#升星 {角色名稱}` 來提昇角色星數\n_小提示:將開頭符號 `#` 改為 `!` 可以跳過確認步驟_",
"full_rank_up_manual": "請輸入 `#升滿星 {角色名稱}` 可一次將角色升滿星\n_小提示:將開頭符號 `#` 改為 `!` 可以跳過確認步驟_",
"full_rank_up_confirm": "確定要花費 *{{ cost }}* 將 *{{ name }}* 升滿星嗎?\n請改輸入 `!升滿星 {{ name }}`\n手機用戶可直接點擊上面按鈕",
"full_rank_up_success": "成功將 *{{ name }}* 升滿星"
}
},
"advancement": {
Expand Down
28 changes: 28 additions & 0 deletions app/migrations/20240909065404_add_attribute_column_to_inventory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return knex.schema
.table("Inventory", table => {
table.json("attributes").after("itemAmount");
})
.then(() =>
knex.raw(`
UPDATE \`Inventory\` i
JOIN \`GachaPool\` g ON i.\`itemId\` = g.\`ID\`
SET i.\`attributes\` = JSON_SET(COALESCE(i.\`attributes\`, '[]'), '$[0]', JSON_OBJECT('key', 'star', 'value', CAST(g.\`Star\` AS UNSIGNED)))
WHERE g.\`Star\` IS NOT NULL;
`)
);
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return knex.schema.table("Inventory", table => {
table.dropColumn("attributes");
});
};
17 changes: 17 additions & 0 deletions app/migrations/20240912090806_drop_gacha_signin_table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return knex.schema.dropTable("GachaSignin");
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return knex.schema.createTable("GachaSignin", table => {
table.increments("id").primary().comment("為了 rollback 用的");
});
};
2 changes: 2 additions & 0 deletions app/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const WorldBossController = require("./controller/application/WorldBossControlle
const GuildServiceController = require("./controller/application/GuildServiceController");
const AdvertisementController = require("./controller/application/AdvertisementController");
const GodStoneShopController = require("./controller/princess/GodStoneShop");
const CharacterController = require("./controller/princess/character");
const JankenController = require("./controller/application/JankenController");
const AdvancementController = require("./controller/application/AdvancementController");
const DonateListController = require("./controller/application/DonateListController");
Expand Down Expand Up @@ -158,6 +159,7 @@ async function OrderBased(context, { next }) {
...SubscribeController.router,
...ScratchCardController.router,
...NumberController.router,
...CharacterController.router,
...(type === "user" ? JobController.router : []),
...(type === "user" ? SubscribeController.privateRouter : []),
text(/^[/#.](使|help)$/, welcome),
Expand Down
27 changes: 27 additions & 0 deletions app/src/controller/application/ChatLevelController.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const { get, sample, set } = require("lodash");
const config = require("config");
const moment = require("moment");
const i18n = require("../../util/i18n");
const { inventory } = require("../../model/application/Inventory");

/**
* 顯示個人狀態,現複合了其他布丁系統的資訊
Expand Down Expand Up @@ -69,6 +70,7 @@ exports.showStatus = async (context, props) => {
achievement,
subscribeInfo,
gachaHistory,
gachaProgress,
] = await Promise.all([
GachaModel.getUserCollectedCharacterCount(userId),
GachaModel.getPrincessCharacterCount(),
Expand All @@ -82,6 +84,7 @@ exports.showStatus = async (context, props) => {
AdvancementModel.findUserAdvancementsByPlatformId(userId),
getSubscribeInfo(userId),
getGachaHistory(userId),
getGachaCollectProgress(userId),
]);

let subInfo;
Expand Down Expand Up @@ -152,6 +155,7 @@ exports.showStatus = async (context, props) => {
godStone,
paidStone: donateAmount || 0,
gachaHistory,
gachaStarProgress: gachaProgress.progress,
});

// ---------- 整理其他雜項數據 ----------
Expand Down Expand Up @@ -212,10 +216,33 @@ exports.showStatus = async (context, props) => {
context.replyText("尚未有任何數據,經驗開始累積後即可投胎!");
}
} catch (e) {
console.error(e);
DefaultLogger.error(e);
}
};

/**
* 取得轉蛋進度
* @param {String} userId
* @returns {Promise<{userTotalStar: Number, totalStarInGame: Number, progress: Number}>}
*/
async function getGachaCollectProgress(userId) {
const ownItems = await inventory.getAllUserOwnCharacters(userId);
const princessCountInGame = await GachaModel.getPrincessCharacterCount();
const userTotalStar = ownItems.reduce((acc, item) => {
const { attributes } = item;
return parseInt(attributes.find(attr => attr.key === "star").value) + acc;
}, 0);

const totalStarInGame = princessCountInGame * 5;

return {
userTotalStar,
totalStarInGame,
progress: Math.floor((userTotalStar / totalStarInGame) * 100),
};
}

async function getGachaHistory(userId) {
const lastRainbowRecord = await GachaRecord.first({
filter: {
Expand Down
1 change: 0 additions & 1 deletion app/src/controller/application/WorldBossController.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const { get, sample, sortBy, isNull } = require("lodash");
const humanNumber = require("human-number");
const { format } = require("util");
const { table, getBorderCharacters } = require("table");
const { parse } = require("path");

exports.router = [
text("#冒險小卡", myStatus),
Expand Down
Loading

0 comments on commit fc69a6c

Please sign in to comment.