feat: panel
|
|
@ -36,7 +36,6 @@ export class Card extends ZZZPlugin {
|
|||
});
|
||||
if (!zzzBuddyList) return false;
|
||||
indexData.buddy_list = zzzBuddyList.list;
|
||||
|
||||
const finalIndexData = new ZZZIndexResp(indexData);
|
||||
this.e.playerCard.player.region_name =
|
||||
finalIndexData.stats.world_level_name;
|
||||
|
|
|
|||
|
|
@ -103,10 +103,12 @@ export class GachaLog extends ZZZPlugin {
|
|||
}
|
||||
await redis.set(`ZZZ:GACHA:${uid}:LASTTIME`, Date.now());
|
||||
this.reply('正在更新抽卡记录,可能需要一段时间,请耐心等待');
|
||||
const data = await updateGachaLog(key, uid);
|
||||
const { data, count } = await updateGachaLog(key, uid);
|
||||
let msg = `抽卡记录更新成功,共${Object.keys(data).length}个卡池`;
|
||||
for (const name in data) {
|
||||
msg += `\n${name}一共${data[name].length}条记录`;
|
||||
msg += `\n${name}一共${data[name].length}条记录,新增${
|
||||
count[name] || 0
|
||||
}条记录`;
|
||||
}
|
||||
await this.reply(msg);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ export class Panel extends ZZZPlugin {
|
|||
},
|
||||
{
|
||||
reg: `${rulePrefix}面板列表$`,
|
||||
fnc: 'getPanelList',
|
||||
fnc: 'getCharPanelList',
|
||||
},
|
||||
{
|
||||
reg: `${rulePrefix}(.+)面板$`,
|
||||
fnc: 'getPanel',
|
||||
fnc: 'getCharPanel',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
@ -32,10 +32,11 @@ export class Panel extends ZZZPlugin {
|
|||
await this.getPlayerInfo();
|
||||
const result = await refreshPanel(this.e, api, uid, deviceFp);
|
||||
const newChar = result.filter(item => item.isNew);
|
||||
let str = '面板列表获取成功,本次共刷新了' + newChar.length + '个角色:';
|
||||
let str = '面板列表获取成功,本次共刷新了' + newChar.length + '个角色:\n';
|
||||
for (const item of result) {
|
||||
str += '\n' + item.name_mi18n;
|
||||
str += item.name_mi18n + (item.isNew ? '(新)' : '') + '、';
|
||||
}
|
||||
str = str.slice(0, -1);
|
||||
str += '\n总计' + result.length + '个角色';
|
||||
await this.reply(str);
|
||||
// const finalData = {
|
||||
|
|
@ -43,7 +44,7 @@ export class Panel extends ZZZPlugin {
|
|||
// };
|
||||
// await render(this.e, 'panel/refresh.html', finalData);
|
||||
}
|
||||
async getPanelList() {
|
||||
async getCharPanelList() {
|
||||
const uid = await this.getUID();
|
||||
if (!uid) return false;
|
||||
const noteData = getPanelList(uid);
|
||||
|
|
@ -59,16 +60,20 @@ export class Panel extends ZZZPlugin {
|
|||
// };
|
||||
// await render(this.e, 'panel/list.html', finalData);
|
||||
}
|
||||
async getPanel() {
|
||||
async getCharPanel() {
|
||||
const uid = await this.getUID();
|
||||
if (!uid) return false;
|
||||
const reg = new RegExp(`${rulePrefix}(.+)面板$`);
|
||||
const name = this.e.msg.match(reg)[4];
|
||||
const data = getPanel(uid, name);
|
||||
await this.reply(JSON.stringify(data, null, 2));
|
||||
// const finalData = {
|
||||
// list: noteData,
|
||||
// };
|
||||
// await render(this.e, 'panel/list.html', finalData);
|
||||
if (!data) {
|
||||
await this.reply(`未找到角色${name}的面板信息`);
|
||||
return false;
|
||||
}
|
||||
await data.get_detail_assets();
|
||||
const finalData = {
|
||||
charData: data,
|
||||
};
|
||||
await render(this.e, 'panel/card.html', finalData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,10 +96,11 @@ export function getPanelList(uid) {
|
|||
* @returns {ZZZAvatarInfo | null}
|
||||
*/
|
||||
export function getPanel(uid, name) {
|
||||
logger.debug('获取面板数据', uid, name);
|
||||
const data = getPanelData(uid).map(item => new ZZZAvatarInfo(item));
|
||||
const _data = getPanelData(uid);
|
||||
const data = _data.map(item => new ZZZAvatarInfo(item));
|
||||
const id = char.atlasToID(name);
|
||||
logger.debug('获取角色ID', id);
|
||||
if (!id) return null;
|
||||
return data.find(item => item.id === id) || null;
|
||||
const result = data.find(item => item.id === id);
|
||||
if (!result) return null;
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,3 +3,9 @@ export * as element from './convert/element.js';
|
|||
export * as char from './convert/char.js';
|
||||
|
||||
export * as weapon from './convert/weapon.js';
|
||||
|
||||
export * as equip from './convert/equip.js';
|
||||
|
||||
export * as rank from './convert/rank.js';
|
||||
|
||||
export * as property from './convert/property.js';
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export const IDToCharName = (id, full = true, en = false) => {
|
|||
export const IDToCharSprite = id => {
|
||||
const data = PartnerId2SpriteId?.[id];
|
||||
if (!data) return null;
|
||||
return data?.['sprite'];
|
||||
return data?.['sprite_id'];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
19
lib/convert/equip.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { getMapData } from '../../utils/file.js';
|
||||
|
||||
const equipData = getMapData('EquipId2Data');
|
||||
|
||||
/**
|
||||
* 获取驱动盘装备的图片
|
||||
* @param {string | number} equipId
|
||||
* @returns {string | null}
|
||||
*/
|
||||
export function equipIdToSprite(equipId) {
|
||||
equipId = equipId.toString();
|
||||
if (equipId.length === 5) {
|
||||
const suitId = equipId.slice(0, 3) + '00';
|
||||
if (equipData.hasOwnProperty(suitId)) {
|
||||
return equipData[suitId]['sprite_file'].replace('3D', '');
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
41
lib/convert/property.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
const prop_id = {
|
||||
111: 'hpmax',
|
||||
121: 'attack',
|
||||
131: 'def',
|
||||
122: 'breakstun',
|
||||
201: 'crit',
|
||||
211: 'critdam',
|
||||
314: 'elementabnormalpower',
|
||||
312: 'elementmystery',
|
||||
231: 'penratio',
|
||||
232: 'penvalue',
|
||||
305: 'sprecover',
|
||||
310: 'spgetratio',
|
||||
115: 'spmax',
|
||||
315: 'physdmg',
|
||||
316: 'fire',
|
||||
317: 'ice',
|
||||
318: 'thunder',
|
||||
319: 'dungeonbuffether',
|
||||
};
|
||||
|
||||
const pro_id = {
|
||||
1: 'attack',
|
||||
2: 'stun',
|
||||
3: 'anomaly',
|
||||
4: 'support',
|
||||
5: 'defense',
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取属性css类名
|
||||
* @param {string} _id 属性id
|
||||
* @returns {string | null}
|
||||
*/
|
||||
export function idToClassName(_id) {
|
||||
let propId = _id.toString();
|
||||
propId = propId.slice(0, 3);
|
||||
const propIcon = prop_id[propId];
|
||||
if (!propIcon) return null;
|
||||
return propIcon;
|
||||
}
|
||||
14
lib/convert/rank.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
const RANK_MAP = {
|
||||
4: 'S',
|
||||
3: 'A',
|
||||
2: 'B',
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取星级对应的字母
|
||||
* @param {string | number} id
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getRankChar(id) {
|
||||
return RANK_MAP[id] || '';
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ import path from 'path';
|
|||
import fs from 'fs';
|
||||
import { ZZZ_SQUARE_AVATAR, ZZZ_SQUARE_BANGBOO } from './mysapi/api.js';
|
||||
import { imageResourcesPath } from './path.js';
|
||||
import { weapon } from './convert.js';
|
||||
import { char, equip, weapon } from './convert.js';
|
||||
import { getResourceRemotePath } from './assets.js';
|
||||
|
||||
const ZZZ_SQUARE_AVATAR_PATH = path.join(imageResourcesPath, 'square_avatar');
|
||||
|
|
@ -11,9 +11,18 @@ const ZZZ_SQUARE_BANGBOO_PATH = path.join(
|
|||
'bangboo_square_avatar'
|
||||
);
|
||||
const ZZZ_WEAPON_PATH = path.join(imageResourcesPath, 'weapon');
|
||||
const ZZZ_GUIDES_PATH = path.join(imageResourcesPath, 'guides');
|
||||
const ZZZ_ROLE_PATH = path.join(imageResourcesPath, 'role');
|
||||
const ZZZ_ROLE_CIRCLE_PATH = path.join(imageResourcesPath, 'role_circle');
|
||||
const ZZZ_SUIT_3D_PATH = path.join(imageResourcesPath, 'suit_3d');
|
||||
const ZZZ_SUIT_PATH = path.join(imageResourcesPath, 'suit');
|
||||
// const ZZZ_GUIDES_PATH = path.join(imageResourcesPath, 'guides');
|
||||
|
||||
// 将下面的下载封装起来,支持错误重试5次
|
||||
/**
|
||||
* 下载文件
|
||||
* @param {string} url 下载地址
|
||||
* @param {string} savePath 保存路径
|
||||
* @returns
|
||||
*/
|
||||
const downloadFile = async (url, savePath) => {
|
||||
const _download = async (url, savePath, retry = 0) => {
|
||||
if (retry > 5) {
|
||||
|
|
@ -36,7 +45,7 @@ const downloadFile = async (url, savePath) => {
|
|||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* 获取角色头像(方形)
|
||||
* @param {string | number} charID
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
|
|
@ -51,7 +60,7 @@ export const getSquareAvatar = async charID => {
|
|||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* 获取邦布头像(方形)
|
||||
* @param {string | number} bangbooId
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
|
|
@ -66,7 +75,7 @@ export const getSquareBangboo = async bangbooId => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get weapon image path
|
||||
* 获取武器图片
|
||||
* @param {string} id
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
|
|
@ -80,6 +89,72 @@ export const getWeaponImage = async id => {
|
|||
const url = await getResourceRemotePath('weapon', filename);
|
||||
const savePath = weaponPath;
|
||||
const download = await downloadFile(url, savePath);
|
||||
logger.mark('getWeaponImage', download);
|
||||
logger.debug('getWeaponImage', download);
|
||||
return download;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取角色图片
|
||||
* @param {string | number} id
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
export const getRoleImage = async id => {
|
||||
const sprite = char.IDToCharSprite(id);
|
||||
if (sprite === null) return null;
|
||||
const filename = `IconRole${sprite}.png`;
|
||||
const rolePath = path.join(ZZZ_ROLE_PATH, filename);
|
||||
if (fs.existsSync(rolePath)) return rolePath;
|
||||
const url = await getResourceRemotePath('role', filename);
|
||||
const savePath = rolePath;
|
||||
const download = await downloadFile(url, savePath);
|
||||
return download;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取角色圆形图片
|
||||
* @param {string | number} id
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
export const getRoleCircleImage = async id => {
|
||||
const sprite = char.IDToCharSprite(id);
|
||||
if (sprite === null) return null;
|
||||
const filename = `IconRoleCircle${sprite}.png`;
|
||||
const roleCirclePath = path.join(ZZZ_ROLE_CIRCLE_PATH, filename);
|
||||
if (fs.existsSync(roleCirclePath)) return roleCirclePath;
|
||||
const url = await getResourceRemotePath('role_circle', filename);
|
||||
const savePath = roleCirclePath;
|
||||
const download = await downloadFile(url, savePath);
|
||||
return download;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取套装图片
|
||||
* @param {string | number} suitId
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
export const getSuitImage = async suitId => {
|
||||
const suitName = equip.equipIdToSprite(suitId);
|
||||
const filename = `${suitName}.png`;
|
||||
const suitPath = path.join(ZZZ_SUIT_PATH, filename);
|
||||
if (fs.existsSync(suitPath)) return suitPath;
|
||||
const url = await getResourceRemotePath('suit', filename);
|
||||
const savePath = suitPath;
|
||||
const download = await downloadFile(url, savePath);
|
||||
return download;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取3D套装图片
|
||||
* @param {string | number} suitId
|
||||
* @returns Promise<string>
|
||||
*/
|
||||
export const getSuit3DImage = async suitId => {
|
||||
const suitName = equip.equipIdToSprite(suitId);
|
||||
const filename = `${suitName}_3d.png`;
|
||||
const suitPath = path.join(ZZZ_SUIT_3D_PATH, filename);
|
||||
if (fs.existsSync(suitPath)) return suitPath;
|
||||
const url = await getResourceRemotePath('suit_3d', filename);
|
||||
const savePath = suitPath;
|
||||
const download = await downloadFile(url, savePath);
|
||||
return download;
|
||||
};
|
||||
|
|
|
|||
65
lib/gacha.js
|
|
@ -1,5 +1,6 @@
|
|||
import { SingleGachaLog, ZZZGachaLogResp } from '../model/gacha.js';
|
||||
import { sleep } from '../utils/time.js';
|
||||
import { rank } from './convert.js';
|
||||
import { getGachaLog, saveGachaLog } from './db.js';
|
||||
import { ZZZ_GET_GACHA_LOG_API } from './mysapi/api.js';
|
||||
|
||||
|
|
@ -96,7 +97,12 @@ export async function getZZZGachaLogByAuthkey(
|
|||
* @param {string} authKey
|
||||
* @param {string} uid
|
||||
* @returns {Promise<{
|
||||
* [x: string]: SingleGachaLog[];
|
||||
* data: {
|
||||
* [x: string]: SingleGachaLog[];
|
||||
* },
|
||||
* count: {
|
||||
* [x: string]: number;
|
||||
* }
|
||||
* }>}
|
||||
*/
|
||||
export async function updateGachaLog(authKey, uid) {
|
||||
|
|
@ -104,26 +110,13 @@ export async function updateGachaLog(authKey, uid) {
|
|||
if (!previousLog) {
|
||||
previousLog = {};
|
||||
}
|
||||
let newCount = {};
|
||||
for (const name in gacha_type_meta_data) {
|
||||
if (!previousLog[name]) {
|
||||
previousLog[name] = [];
|
||||
}
|
||||
previousLog[name] = previousLog[name].map(
|
||||
i =>
|
||||
new SingleGachaLog(
|
||||
i.uid,
|
||||
i.gacha_id,
|
||||
i.gacha_type,
|
||||
i.item_id,
|
||||
i.count,
|
||||
i.time,
|
||||
i.name,
|
||||
i.lang,
|
||||
i.item_type,
|
||||
i.rank_type,
|
||||
i.id
|
||||
)
|
||||
);
|
||||
newCount[name] = 0;
|
||||
previousLog[name] = previousLog[name].map(i => new SingleGachaLog(i));
|
||||
const lastSaved = previousLog[name]?.[0];
|
||||
let page = 1;
|
||||
let endId = '0';
|
||||
|
|
@ -145,6 +138,7 @@ export async function updateGachaLog(authKey, uid) {
|
|||
break queryLabel;
|
||||
}
|
||||
newData.push(item);
|
||||
newCount[name]++;
|
||||
}
|
||||
endId = log.list[log.list.length - 1]?.id || endId;
|
||||
page++;
|
||||
|
|
@ -154,14 +148,12 @@ export async function updateGachaLog(authKey, uid) {
|
|||
previousLog[name] = [...newData, ...previousLog[name]];
|
||||
}
|
||||
saveGachaLog(uid, previousLog);
|
||||
return previousLog;
|
||||
return {
|
||||
data: previousLog,
|
||||
count: newCount,
|
||||
};
|
||||
}
|
||||
|
||||
const RANK_MAP = {
|
||||
4: 'S',
|
||||
3: 'A',
|
||||
2: 'B',
|
||||
};
|
||||
const HOMO_TAG = ['非到极致', '运气不好', '平稳保底', '小欧一把', '欧狗在此'];
|
||||
const EMOJI = [
|
||||
[4, 8, 13],
|
||||
|
|
@ -186,10 +178,10 @@ const NORMAL_LIST = [
|
|||
];
|
||||
|
||||
const FLOORS_MAP = {
|
||||
'邦布频段': [50, 70],
|
||||
'音擎频段': [50, 70],
|
||||
'独家频段': [60, 80],
|
||||
'常驻频段': [60, 80],
|
||||
邦布频段: [50, 70],
|
||||
音擎频段: [50, 70],
|
||||
独家频段: [60, 80],
|
||||
常驻频段: [60, 80],
|
||||
};
|
||||
|
||||
function getLevelFromList(ast, lst) {
|
||||
|
|
@ -214,22 +206,7 @@ export async function anaylizeGachaLog(uid) {
|
|||
}
|
||||
const result = [];
|
||||
for (const name in savedData) {
|
||||
const data = savedData[name].map(
|
||||
item =>
|
||||
new SingleGachaLog(
|
||||
item.uid,
|
||||
item.gacha_id,
|
||||
item.gacha_type,
|
||||
item.item_id,
|
||||
item.count,
|
||||
item.time,
|
||||
item.name,
|
||||
item.lang,
|
||||
item.item_type,
|
||||
item.rank_type,
|
||||
item.id
|
||||
)
|
||||
);
|
||||
const data = savedData[name].map(item => new SingleGachaLog(item));
|
||||
const earliest = data[data.length - 1];
|
||||
const latest = data[0];
|
||||
const list = [];
|
||||
|
|
@ -256,7 +233,7 @@ export async function anaylizeGachaLog(uid) {
|
|||
}
|
||||
list.push({
|
||||
...item,
|
||||
rank_type_label: RANK_MAP[item.rank_type],
|
||||
rank_type_label: rank.getRankChar(item.rank_type),
|
||||
isUp: isUp,
|
||||
totalCount: '-',
|
||||
color: 'white',
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ function render(e, renderPath, renderData = {}, cfg = {}) {
|
|||
resourcesPath: resPath,
|
||||
currentPath: renderPathFull,
|
||||
playerInfo: path.join(layoutPathFull, 'playerinfo.html'),
|
||||
specialTitle: path.join(layoutPathFull, 'specialtitle.html'),
|
||||
copyright: `Created By ${version.name}<span class="version">${version.yunzai}</span> & ${pluginName}<span class="version">${version.version}</span>`,
|
||||
createdby: `Created By <span class="highlight">${pluginName}</span> & Powered By <span class="highlight">ZZZure</span>`,
|
||||
},
|
||||
|
|
|
|||
118
model/avatar.js
|
|
@ -1,5 +1,5 @@
|
|||
import { element } from '../lib/convert.js';
|
||||
import { getSquareAvatar } from '../lib/download.js';
|
||||
import { getRoleImage, getSquareAvatar } from '../lib/download.js';
|
||||
import { Equip, Weapon } from './equip.js';
|
||||
import { Property } from './property.js';
|
||||
import { Skill } from './skill.js';
|
||||
|
|
@ -114,20 +114,40 @@ export class ZZZAvatarBasic {
|
|||
|
||||
this.element_str = element.IDToElement(element_type);
|
||||
}
|
||||
|
||||
async get_assets() {
|
||||
const result = await getSquareAvatar(this.id);
|
||||
this.square_icon = result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @class
|
||||
*/
|
||||
export class Rank {
|
||||
// 类型标注
|
||||
/** @type {number} */
|
||||
id;
|
||||
/** @type {string} */
|
||||
name;
|
||||
/** @type {string} */
|
||||
desc;
|
||||
/** @type {number} */
|
||||
pos;
|
||||
/** @type {boolean} */
|
||||
is_unlocked;
|
||||
|
||||
/**
|
||||
* @param {number} id
|
||||
* @param {string} name
|
||||
* @param {string} desc
|
||||
* @param {number} pos
|
||||
* @param {boolean} is_unlocked
|
||||
* @param {{
|
||||
* id: number;
|
||||
* name: string;
|
||||
* desc: string;
|
||||
* pos: number;
|
||||
* is_unlocked: boolean;
|
||||
* }} data
|
||||
*/
|
||||
constructor(id, name, desc, pos, is_unlocked) {
|
||||
constructor(data) {
|
||||
const { id, name, desc, pos, is_unlocked } = data;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.desc = desc;
|
||||
|
|
@ -158,11 +178,46 @@ export class ZZZAvatarInfo {
|
|||
* skills: Skill[];
|
||||
* rank: number;
|
||||
* ranks: Rank[];
|
||||
*
|
||||
* isNew?: boolean;
|
||||
* }} data
|
||||
*/
|
||||
constructor(data) {
|
||||
// 类型标注
|
||||
/** @type {number} */
|
||||
this.id;
|
||||
/** @type {number} */
|
||||
this.level;
|
||||
/** @type {string} */
|
||||
this.name_mi18n;
|
||||
/** @type {string} */
|
||||
this.full_name_mi18n;
|
||||
/** @type {number} */
|
||||
this.element_type;
|
||||
/** @type {string} */
|
||||
this.camp_name_mi18n;
|
||||
/** @type {number} */
|
||||
this.avatar_profession;
|
||||
/** @type {string} */
|
||||
this.rarity;
|
||||
/** @type {string} */
|
||||
this.group_icon_path;
|
||||
/** @type {string} */
|
||||
this.hollow_icon_path;
|
||||
/** @type {Equip[]} */
|
||||
this.equip;
|
||||
/** @type {Weapon} */
|
||||
this.weapon;
|
||||
/** @type {Property[]} */
|
||||
this.properties;
|
||||
/** @type {Skill[]} */
|
||||
this.skills;
|
||||
/** @type {number} */
|
||||
this.rank;
|
||||
/** @type {Rank[]} */
|
||||
this.ranks;
|
||||
/** @type {boolean} */
|
||||
this.isNew;
|
||||
|
||||
const {
|
||||
id,
|
||||
level,
|
||||
|
|
@ -192,22 +247,59 @@ export class ZZZAvatarInfo {
|
|||
this.rarity = rarity;
|
||||
this.group_icon_path = group_icon_path;
|
||||
this.hollow_icon_path = hollow_icon_path;
|
||||
this.equip = equip;
|
||||
this.weapon = weapon;
|
||||
this.properties = properties;
|
||||
this.skills = skills;
|
||||
this.equip =
|
||||
equip &&
|
||||
(Array.isArray(equip)
|
||||
? equip.map(equip => new Equip(equip))
|
||||
: new Equip(equip));
|
||||
this.weapon = weapon ? new Weapon(weapon) : null;
|
||||
this.properties =
|
||||
properties && properties.map(property => new Property(property));
|
||||
this.skills = skills && skills.map(skill => new Skill(skill));
|
||||
this.rank = rank;
|
||||
this.ranks = ranks;
|
||||
this.ranks = ranks && ranks.map(rank => new Rank(rank));
|
||||
|
||||
this.ranks_num = this.ranks.filter(rank => rank.is_unlocked).length;
|
||||
|
||||
this.element_str = element.IDToElement(element_type);
|
||||
this.isNew = isNew;
|
||||
}
|
||||
|
||||
getProperty(name) {
|
||||
return this.properties.find(property => property.property_name === name);
|
||||
}
|
||||
|
||||
get basic_properties() {
|
||||
const data = {
|
||||
hpmax: this.getProperty('生命值'),
|
||||
attack: this.getProperty('攻击力'),
|
||||
def: this.getProperty('防御力'),
|
||||
breakstun: this.getProperty('冲击力'),
|
||||
crit: this.getProperty('暴击率'),
|
||||
critdam: this.getProperty('暴击伤害'),
|
||||
elementabnormalpower: this.getProperty('异常掌控'),
|
||||
elementmystery: this.getProperty('异常精通'),
|
||||
penratio: this.getProperty('穿透率'),
|
||||
sprecover: this.getProperty('能量自动回复'),
|
||||
};
|
||||
logger.debug('basic_properties', data);
|
||||
return data;
|
||||
}
|
||||
|
||||
async get_basic_assets() {
|
||||
const result = await getSquareAvatar(this.id);
|
||||
this.square_icon = result;
|
||||
}
|
||||
|
||||
async get_detail_assets() {
|
||||
const role_icon = await getRoleImage(this.id);
|
||||
this.role_icon = role_icon;
|
||||
await this.weapon.get_assets();
|
||||
for (const equip of this.equip) {
|
||||
await equip.get_assets();
|
||||
}
|
||||
}
|
||||
|
||||
async get_assets() {
|
||||
await this.get_basic_assets();
|
||||
}
|
||||
|
|
|
|||
209
model/equip.js
|
|
@ -1,16 +1,34 @@
|
|||
import { property } from '../lib/convert.js';
|
||||
import { getSuitImage, getWeaponImage } from '../lib/download.js';
|
||||
|
||||
/**
|
||||
* @class
|
||||
*/
|
||||
export class EquipProperty {
|
||||
// 类型标注
|
||||
/** @type {string} */
|
||||
property_name;
|
||||
/** @type {number} */
|
||||
property_id;
|
||||
/** @type {string} */
|
||||
base;
|
||||
/** @type {string} */
|
||||
classname;
|
||||
|
||||
/**
|
||||
* @param {string} property_name
|
||||
* @param {number} property_id
|
||||
* @param {string} base
|
||||
* @param {{
|
||||
* property_name: string;
|
||||
* property_id: number;
|
||||
* base: string
|
||||
* }} data
|
||||
*/
|
||||
constructor(property_name, property_id, base) {
|
||||
constructor(data) {
|
||||
const { property_name, property_id, base } = data;
|
||||
this.property_name = property_name;
|
||||
this.property_id = property_id;
|
||||
this.base = base;
|
||||
|
||||
this.classname = property.idToClassName(property_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -18,15 +36,30 @@ export class EquipProperty {
|
|||
* @class
|
||||
*/
|
||||
export class EquipMainProperty {
|
||||
// 类型标注
|
||||
/** @type {string} */
|
||||
property_name;
|
||||
/** @type {number} */
|
||||
property_id;
|
||||
/** @type {string} */
|
||||
base;
|
||||
/** @type {string} */
|
||||
classname;
|
||||
|
||||
/**
|
||||
* @param {string} property_name
|
||||
* @param {number} property_id
|
||||
* @param {string} base
|
||||
* @param {{
|
||||
* property_name: string;
|
||||
* property_id: number;
|
||||
* base: string;
|
||||
* }} data
|
||||
*/
|
||||
constructor(property_name, property_id, base) {
|
||||
constructor(data) {
|
||||
const { property_name, property_id, base } = data;
|
||||
this.property_name = property_name;
|
||||
this.property_id = property_id;
|
||||
this.base = base;
|
||||
|
||||
this.classname = property.idToClassName(property_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,79 +88,143 @@ export class EquipSuit {
|
|||
*/
|
||||
export class Equip {
|
||||
/**
|
||||
* @param {number} id
|
||||
* @param {number} level
|
||||
* @param {string} name
|
||||
* @param {string} icon
|
||||
* @param {string} rarity
|
||||
* @param {EquipProperty[]} properties
|
||||
* @param {EquipMainProperty[]} main_properties
|
||||
* @param {EquipSuit} equip_suit
|
||||
* @param {number} equipment_type
|
||||
* @param {{
|
||||
* id: number;
|
||||
* level: number;
|
||||
* name: string;
|
||||
* icon: string;
|
||||
* rarity: string;
|
||||
* properties: EquipProperty[];
|
||||
* main_properties: EquipMainProperty[];
|
||||
* equip_suit: EquipSuit;
|
||||
* equipment_type: number;
|
||||
* }} data
|
||||
*/
|
||||
constructor(
|
||||
id,
|
||||
level,
|
||||
name,
|
||||
icon,
|
||||
rarity,
|
||||
properties,
|
||||
main_properties,
|
||||
equip_suit,
|
||||
equipment_type
|
||||
) {
|
||||
constructor(data) {
|
||||
// 类型标注
|
||||
/** @type {number} */
|
||||
this.id;
|
||||
/** @type {number} */
|
||||
this.level;
|
||||
/** @type {string} */
|
||||
this.name;
|
||||
/** @type {string} */
|
||||
this.icon;
|
||||
/** @type {string} */
|
||||
this.rarity;
|
||||
/** @type {EquipProperty[]} */
|
||||
this.properties;
|
||||
/** @type {EquipMainProperty[]} */
|
||||
this.main_properties;
|
||||
/** @type {EquipSuit} */
|
||||
this.equip_suit;
|
||||
/** @type {number} */
|
||||
this.equipment_type;
|
||||
|
||||
const {
|
||||
id,
|
||||
level,
|
||||
name,
|
||||
icon,
|
||||
rarity,
|
||||
properties,
|
||||
main_properties,
|
||||
equip_suit,
|
||||
equipment_type,
|
||||
} = data;
|
||||
this.id = id;
|
||||
this.level = level;
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.rarity = rarity;
|
||||
this.properties = properties;
|
||||
this.main_properties = main_properties;
|
||||
this.properties = properties.map(item => new EquipProperty(item));
|
||||
this.main_properties = main_properties.map(
|
||||
item => new EquipMainProperty(item)
|
||||
);
|
||||
this.equip_suit = equip_suit;
|
||||
this.equipment_type = equipment_type;
|
||||
}
|
||||
|
||||
async get_assets() {
|
||||
const result = await getSuitImage(this.id);
|
||||
this.suit_icon = result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @class
|
||||
*/
|
||||
export class Weapon {
|
||||
// 类型标注
|
||||
/** @type {number} */
|
||||
id;
|
||||
/** @type {number} */
|
||||
level;
|
||||
/** @type {string} */
|
||||
name;
|
||||
/** @type {number} */
|
||||
star;
|
||||
/** @type {string} */
|
||||
icon;
|
||||
/** @type {string} */
|
||||
rarity;
|
||||
/** @type {EquipProperty[]} */
|
||||
properties;
|
||||
/** @type {EquipMainProperty[]} */
|
||||
main_properties;
|
||||
/** @type {string} */
|
||||
talent_title;
|
||||
/** @type {string} */
|
||||
talent_content;
|
||||
/** @type {number} */
|
||||
profession;
|
||||
|
||||
/**
|
||||
* @param {number} id
|
||||
* @param {number} level
|
||||
* @param {string} name
|
||||
* @param {number} star
|
||||
* @param {string} icon
|
||||
* @param {string} rarity
|
||||
* @param {EquipProperty[]} properties
|
||||
* @param {EquipMainProperty[]} main_properties
|
||||
* @param {string} talent_title
|
||||
* @param {string} talent_content
|
||||
* @param {number} profession
|
||||
* @param {{
|
||||
* id: number;
|
||||
* level: number;
|
||||
* name: string;
|
||||
* star: number;
|
||||
* icon: string;
|
||||
* rarity: string;
|
||||
* properties: EquipProperty[];
|
||||
* main_properties: EquipMainProperty[];
|
||||
* talent_title: string;
|
||||
* talent_content: string;
|
||||
* profession: number;
|
||||
* }} data
|
||||
*/
|
||||
constructor(
|
||||
id,
|
||||
level,
|
||||
name,
|
||||
star,
|
||||
icon,
|
||||
rarity,
|
||||
properties,
|
||||
main_properties,
|
||||
talent_title,
|
||||
talent_content,
|
||||
profession
|
||||
) {
|
||||
constructor(data) {
|
||||
const {
|
||||
id,
|
||||
level,
|
||||
name,
|
||||
star,
|
||||
icon,
|
||||
rarity,
|
||||
properties,
|
||||
main_properties,
|
||||
talent_title,
|
||||
talent_content,
|
||||
profession,
|
||||
} = data;
|
||||
this.id = id;
|
||||
this.level = level;
|
||||
this.name = name;
|
||||
this.star = star;
|
||||
this.icon = icon;
|
||||
this.rarity = rarity;
|
||||
this.properties = properties;
|
||||
this.main_properties = main_properties;
|
||||
this.properties = properties.map(item => new EquipProperty(item));
|
||||
this.main_properties = main_properties.map(
|
||||
item => new EquipMainProperty(item)
|
||||
);
|
||||
this.talent_title = talent_title;
|
||||
this.talent_content = talent_content;
|
||||
this.profession = profession;
|
||||
}
|
||||
|
||||
async get_assets() {
|
||||
const result = await getWeaponImage(this.id);
|
||||
this.square_icon = result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,32 +8,58 @@ import {
|
|||
* @class
|
||||
*/
|
||||
export class SingleGachaLog {
|
||||
// 类型标注
|
||||
/** @type {string} */
|
||||
uid;
|
||||
/** @type {string} */
|
||||
gacha_id;
|
||||
/** @type {string} */
|
||||
gacha_type;
|
||||
/** @type {string} */
|
||||
item_id;
|
||||
/** @type {string} */
|
||||
count;
|
||||
/** @type {string} */
|
||||
time;
|
||||
/** @type {string} */
|
||||
name;
|
||||
/** @type {string} */
|
||||
lang;
|
||||
/** @type {string} */
|
||||
item_type;
|
||||
/** @type {string} */
|
||||
rank_type;
|
||||
/** @type {string} */
|
||||
id;
|
||||
/**
|
||||
* @param {string} uid
|
||||
* @param {string} gacha_id
|
||||
* @param {string} gacha_type
|
||||
* @param {string} item_id
|
||||
* @param {string} count
|
||||
* @param {string} time
|
||||
* @param {string} name
|
||||
* @param {string} lang
|
||||
* @param {string} item_type
|
||||
* @param {string} rank_type
|
||||
* @param {string} id
|
||||
* @param {{
|
||||
* uid: string;
|
||||
* gacha_id: string;
|
||||
* gacha_type: string;
|
||||
* item_id: string;
|
||||
* count: string;
|
||||
* time: string;
|
||||
* name: string;
|
||||
* lang: string;
|
||||
* item_type: string;
|
||||
* rank_type: string;
|
||||
* id: string;
|
||||
* }} data
|
||||
*/
|
||||
constructor(
|
||||
uid,
|
||||
gacha_id,
|
||||
gacha_type,
|
||||
item_id,
|
||||
count,
|
||||
time,
|
||||
name,
|
||||
lang,
|
||||
item_type,
|
||||
rank_type,
|
||||
id
|
||||
) {
|
||||
constructor(data) {
|
||||
const {
|
||||
uid,
|
||||
gacha_id,
|
||||
gacha_type,
|
||||
item_id,
|
||||
count,
|
||||
time,
|
||||
name,
|
||||
lang,
|
||||
item_type,
|
||||
rank_type,
|
||||
id,
|
||||
} = data;
|
||||
this.uid = uid;
|
||||
this.gacha_id = gacha_id;
|
||||
this.gacha_type = gacha_type;
|
||||
|
|
@ -93,22 +119,7 @@ export class ZZZGachaLogResp {
|
|||
const { page, size, list, region, region_time_zone } = data;
|
||||
this.page = page;
|
||||
this.size = size;
|
||||
this.list = list.map(
|
||||
item =>
|
||||
new SingleGachaLog(
|
||||
item.uid,
|
||||
item.gacha_id,
|
||||
item.gacha_type,
|
||||
item.item_id,
|
||||
item.count,
|
||||
item.time,
|
||||
item.name,
|
||||
item.lang,
|
||||
item.item_type,
|
||||
item.rank_type,
|
||||
item.id
|
||||
)
|
||||
);
|
||||
this.list = list.map(item => new SingleGachaLog(item));
|
||||
this.region = region;
|
||||
this.region_time_zone = region_time_zone;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ZZZAvatarInfo } from './avatar.js';
|
||||
import { ZZZAvatarBasic } from './avatar.js';
|
||||
import { Buddy } from './bangboo.js';
|
||||
|
||||
/**
|
||||
|
|
@ -34,7 +34,7 @@ export class ZZZIndexResp {
|
|||
/**
|
||||
* @param {{
|
||||
* stats: Stats;
|
||||
* avatar_list: ZZZAvatarInfo[];
|
||||
* avatar_list: ZZZAvatarBasic[];
|
||||
* cur_head_icon_url: string;
|
||||
* buddy_list: Buddy[];
|
||||
* }} data
|
||||
|
|
@ -42,7 +42,7 @@ export class ZZZIndexResp {
|
|||
constructor(data) {
|
||||
const { stats, avatar_list, cur_head_icon_url, buddy_list } = data;
|
||||
this.stats = stats;
|
||||
this.avatar_list = avatar_list.map(item => new ZZZAvatarInfo(item));
|
||||
this.avatar_list = avatar_list.map(item => new ZZZAvatarBasic(item));
|
||||
this.cur_head_icon_url = cur_head_icon_url;
|
||||
this.buddy_list = buddy_list.map(item => new Buddy(item));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,21 @@
|
|||
*/
|
||||
export class Property {
|
||||
/**
|
||||
* @param {{
|
||||
* property_name: string,
|
||||
* property_id: number,
|
||||
* base: string,
|
||||
* add: string,
|
||||
* final: string
|
||||
* }} data
|
||||
* @param {string} property_name
|
||||
* @param {number} property_id
|
||||
* @param {string} base
|
||||
* @param {string} add
|
||||
* @param {string} final
|
||||
*/
|
||||
constructor(property_name, property_id, base, add, final) {
|
||||
constructor(data) {
|
||||
const { property_name, property_id, base, add, final } = data;
|
||||
this.property_name = property_name;
|
||||
this.property_id = property_id;
|
||||
this.base = base;
|
||||
|
|
|
|||
|
|
@ -17,11 +17,14 @@ export class SkillItem {
|
|||
*/
|
||||
export class Skill {
|
||||
/**
|
||||
* @param {number} level
|
||||
* @param {number} skill_type
|
||||
* @param {SkillItem[]} items
|
||||
* @param {{
|
||||
* level: number,
|
||||
* skill_type: number,
|
||||
* items: SkillItem[]
|
||||
* }} data
|
||||
*/
|
||||
constructor(level, skill_type, items) {
|
||||
constructor(data) {
|
||||
const { level, skill_type, items } = data;
|
||||
this.level = level;
|
||||
this.skill_type = skill_type;
|
||||
this.items = items;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.card .list .item * {
|
||||
.card .list .item > * {
|
||||
position: inherit;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
@ -82,13 +82,44 @@
|
|||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
.card .list .item .level {
|
||||
.card .list .item .c-info {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background: rgb(0, 0, 0);
|
||||
color: white;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
}
|
||||
.card .list .item .c-info .ranks {
|
||||
background: rgb(117, 117, 117);
|
||||
padding: 0 0.4em;
|
||||
}
|
||||
.card .list .item .c-info .ranks.r1 {
|
||||
background: rgb(58, 116, 43);
|
||||
}
|
||||
.card .list .item .c-info .ranks.r2 {
|
||||
background: rgb(61, 132, 214);
|
||||
}
|
||||
.card .list .item .c-info .ranks.r3 {
|
||||
background: rgb(223, 118, 118);
|
||||
}
|
||||
.card .list .item .c-info .ranks.r4 {
|
||||
background: rgb(51, 54, 161);
|
||||
}
|
||||
.card .list .item .c-info .ranks.r5 {
|
||||
background: rgb(102, 127, 19);
|
||||
}
|
||||
.card .list .item .c-info .ranks.r6 {
|
||||
background: rgb(218, 48, 32);
|
||||
}
|
||||
.card .list .item .c-info .level {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
.card .list .item .property {
|
||||
|
|
|
|||
|
|
@ -25,62 +25,37 @@
|
|||
<div class="label">式舆防卫战</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="special-title">
|
||||
<div class="bg-content">
|
||||
AGENT
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
代理人信息
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="list">
|
||||
{{each card.avatar_list char i}}
|
||||
<div class="item rank{{char.rarity}}">
|
||||
<div class="rank rank-icon {{char.rarity}}"></div>
|
||||
<div class="property {{char.element_str}}"></div>
|
||||
<div class="image">
|
||||
<img src="{{char.square_icon}}" alt="">
|
||||
<% include(sys.specialTitle, {en: 'AGENT' , cn: '代理人信息' }) %>
|
||||
<div class="list">
|
||||
{{each card.avatar_list char i}}
|
||||
<div class="item rank{{char.rarity}}">
|
||||
<div class="rank rank-icon {{char.rarity}}"></div>
|
||||
<div class="property {{char.element_str}}"></div>
|
||||
<div class="image">
|
||||
<img src="{{char.square_icon}}" alt="">
|
||||
</div>
|
||||
<div class="c-info">
|
||||
<div class="ranks r{{char.rank}}">{{char.rank}}命</div>
|
||||
<div class="level">等级{{char.level}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="level">等级{{char.level}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
|
||||
<div class="special-title">
|
||||
<div class="bg-content">
|
||||
BANGBOO
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
邦布信息
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="list">
|
||||
{{each card.buddy_list bangboo i}}
|
||||
<div class="item rank{{bangboo.rarity}}">
|
||||
<div class="rank rank-icon {{bangboo.rarity}}"></div>
|
||||
<div class="image">
|
||||
<img src="{{bangboo.square_icon}}" alt="">
|
||||
<% include(sys.specialTitle, {en: 'BANGBOO' , cn: '邦布信息' }) %>
|
||||
<div class="list">
|
||||
{{each card.buddy_list bangboo i}}
|
||||
<div class="item rank{{bangboo.rarity}}">
|
||||
<div class="rank rank-icon {{bangboo.rarity}}"></div>
|
||||
<div class="image">
|
||||
<img src="{{bangboo.square_icon}}" alt="">
|
||||
</div>
|
||||
<div class="c-info">
|
||||
<div class="ranks r{{bangboo.star}}">{{bangboo.star}}命</div>
|
||||
<div class="level">等级{{bangboo.level}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="level">等级{{bangboo.level}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/block}}
|
||||
|
|
@ -39,7 +39,7 @@
|
|||
.item {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
* {
|
||||
> * {
|
||||
position: inherit;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
@ -83,14 +83,45 @@
|
|||
display: block;
|
||||
}
|
||||
}
|
||||
.level {
|
||||
.c-info {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background: rgb(0, 0, 0);
|
||||
color: white;
|
||||
display: flex;
|
||||
text-align: center;
|
||||
.ranks {
|
||||
background: rgb(117, 117, 117);
|
||||
padding: 0 0.4em;
|
||||
&.r1 {
|
||||
background: rgb(58, 116, 43);
|
||||
}
|
||||
&.r2 {
|
||||
background: rgb(61, 132, 214);
|
||||
}
|
||||
&.r3 {
|
||||
background: rgb(223, 118, 118);
|
||||
}
|
||||
&.r4 {
|
||||
background: rgb(51, 54, 161);
|
||||
}
|
||||
&.r5 {
|
||||
background: rgb(102, 127, 19);
|
||||
}
|
||||
&.r6 {
|
||||
background: rgb(218, 48, 32);
|
||||
}
|
||||
}
|
||||
.level {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.property {
|
||||
position: absolute;
|
||||
|
|
|
|||
BIN
resources/common/images/Rarity_A.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
resources/common/images/Rarity_B.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
resources/common/images/Rarity_C.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
resources/common/images/Rarity_S.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
resources/common/images/Rarity_X.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
resources/common/images/prop/IconAnomaly.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
resources/common/images/prop/IconAttack.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
resources/common/images/prop/IconDefense.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/common/images/prop/IconStun.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
resources/common/images/prop/IconSupport.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/common/images/property/IconAttack.png
Normal file
|
After Width: | Height: | Size: 821 B |
BIN
resources/common/images/property/IconBreakStun.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/common/images/property/IconCrit.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/common/images/property/IconCritDam.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/common/images/property/IconDef.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
resources/common/images/property/IconDungeonBuffEther.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/common/images/property/IconElementAbnormalPower.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/common/images/property/IconElementMystery.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/common/images/property/IconFire.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
resources/common/images/property/IconHpMax.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/common/images/property/IconIce.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
resources/common/images/property/IconPenRatio.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/common/images/property/IconPenValue.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/common/images/property/IconPhysDmg.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/common/images/property/IconSpGetRatio.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
resources/common/images/property/IconSpMax.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/common/images/property/IconSpRecover.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
resources/common/images/property/IconThunder.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
18
resources/common/layout/specialtitle.html
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<div class="special-title">
|
||||
<div class="bg-content">
|
||||
{{en}}
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<% for(let i=1 ; i < (count || 9) ; i++) { %>
|
||||
<span></span>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="content">
|
||||
{{cn}}
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<% for(let i=1 ; i < (count || 9) ; i++) { %>
|
||||
<span></span>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -34,6 +34,28 @@
|
|||
background-image: url("../images/RANK_B.png");
|
||||
}
|
||||
|
||||
.rarity-icon {
|
||||
aspect-ratio: 1;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
}
|
||||
.rarity-icon.a, .rarity-icon.A {
|
||||
background-image: url("../images/Rarity_A.png");
|
||||
}
|
||||
.rarity-icon.b, .rarity-icon.B {
|
||||
background-image: url("../images/Rarity_B.png");
|
||||
}
|
||||
.rarity-icon.c, .rarity-icon.C {
|
||||
background-image: url("../images/Rarity_C.png");
|
||||
}
|
||||
.rarity-icon.s, .rarity-icon.S {
|
||||
background-image: url("../images/Rarity_S.png");
|
||||
}
|
||||
.rarity-icon.x, .rarity-icon.X {
|
||||
background-image: url("../images/Rarity_X.png");
|
||||
}
|
||||
|
||||
.property {
|
||||
aspect-ratio: 1;
|
||||
background-size: contain;
|
||||
|
|
@ -56,6 +78,89 @@
|
|||
background-image: url("../images/IconDungeonBuffEther.png");
|
||||
}
|
||||
|
||||
.prop-icon {
|
||||
aspect-ratio: 1;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.prop-icon.attack {
|
||||
background-image: url("../images/property/IconAttack.png");
|
||||
}
|
||||
.prop-icon.breakstun {
|
||||
background-image: url("../images/property/IconBreakStun.png");
|
||||
}
|
||||
.prop-icon.crit {
|
||||
background-image: url("../images/property/IconCrit.png");
|
||||
}
|
||||
.prop-icon.critdam {
|
||||
background-image: url("../images/property/IconCritDam.png");
|
||||
}
|
||||
.prop-icon.def {
|
||||
background-image: url("../images/property/IconDef.png");
|
||||
}
|
||||
.prop-icon.dungeonbuffether {
|
||||
background-image: url("../images/property/IconDungeonBuffEther.png");
|
||||
}
|
||||
.prop-icon.elementabnormalpower {
|
||||
background-image: url("../images/property/IconElementAbnormalPower.png");
|
||||
}
|
||||
.prop-icon.elementmystery {
|
||||
background-image: url("../images/property/IconElementMystery.png");
|
||||
}
|
||||
.prop-icon.fire {
|
||||
background-image: url("../images/property/IconFire.png");
|
||||
}
|
||||
.prop-icon.hpmax {
|
||||
background-image: url("../images/property/IconHpMax.png");
|
||||
}
|
||||
.prop-icon.ice {
|
||||
background-image: url("../images/property/IconIce.png");
|
||||
}
|
||||
.prop-icon.penratio {
|
||||
background-image: url("../images/property/IconPenRatio.png");
|
||||
}
|
||||
.prop-icon.penvalue {
|
||||
background-image: url("../images/property/IconPenValue.png");
|
||||
}
|
||||
.prop-icon.physdmg {
|
||||
background-image: url("../images/property/IconPhysDmg.png");
|
||||
}
|
||||
.prop-icon.spgetratio {
|
||||
background-image: url("../images/property/IconSpGetRatio.png");
|
||||
}
|
||||
.prop-icon.spmax {
|
||||
background-image: url("../images/property/IconSpMax.png");
|
||||
}
|
||||
.prop-icon.sprecover {
|
||||
background-image: url("../images/property/IconSpRecover.png");
|
||||
}
|
||||
.prop-icon.thunder {
|
||||
background-image: url("../images/property/IconThunder.png");
|
||||
}
|
||||
|
||||
.pro-icon {
|
||||
aspect-ratio: 1;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.pro-icon.anomaly {
|
||||
background-image: url("../images/prop/IconAnomaly.png");
|
||||
}
|
||||
.pro-icon.attack {
|
||||
background-image: url("../images/prop/IconAttack.png");
|
||||
}
|
||||
.pro-icon.defense {
|
||||
background-image: url("../images/prop/IconDefence.png");
|
||||
}
|
||||
.pro-icon.stun {
|
||||
background-image: url("../images/prop/IconStun.png");
|
||||
}
|
||||
.pro-icon.support {
|
||||
background-image: url("../images/prop/IconSupport.png");
|
||||
}
|
||||
|
||||
.special-title {
|
||||
width: 100%;
|
||||
background-size: contain;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,33 @@
|
|||
}
|
||||
}
|
||||
|
||||
.rarity-icon {
|
||||
aspect-ratio: 1;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
&.a,
|
||||
&.A {
|
||||
background-image: url('../images/Rarity_A.png');
|
||||
}
|
||||
&.b,
|
||||
&.B {
|
||||
background-image: url('../images/Rarity_B.png');
|
||||
}
|
||||
&.c,
|
||||
&.C {
|
||||
background-image: url('../images/Rarity_C.png');
|
||||
}
|
||||
&.s,
|
||||
&.S {
|
||||
background-image: url('../images/Rarity_S.png');
|
||||
}
|
||||
&.x,
|
||||
&.X {
|
||||
background-image: url('../images/Rarity_X.png');
|
||||
}
|
||||
}
|
||||
|
||||
.property {
|
||||
aspect-ratio: 1;
|
||||
background-size: contain;
|
||||
|
|
@ -81,6 +108,89 @@
|
|||
}
|
||||
}
|
||||
|
||||
.prop-icon {
|
||||
aspect-ratio: 1;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
&.attack {
|
||||
background-image: url('../images/property/IconAttack.png');
|
||||
}
|
||||
&.breakstun {
|
||||
background-image: url('../images/property/IconBreakStun.png');
|
||||
}
|
||||
&.crit {
|
||||
background-image: url('../images/property/IconCrit.png');
|
||||
}
|
||||
&.critdam {
|
||||
background-image: url('../images/property/IconCritDam.png');
|
||||
}
|
||||
&.def {
|
||||
background-image: url('../images/property/IconDef.png');
|
||||
}
|
||||
&.dungeonbuffether {
|
||||
background-image: url('../images/property/IconDungeonBuffEther.png');
|
||||
}
|
||||
&.elementabnormalpower {
|
||||
background-image: url('../images/property/IconElementAbnormalPower.png');
|
||||
}
|
||||
&.elementmystery {
|
||||
background-image: url('../images/property/IconElementMystery.png');
|
||||
}
|
||||
&.fire {
|
||||
background-image: url('../images/property/IconFire.png');
|
||||
}
|
||||
&.hpmax {
|
||||
background-image: url('../images/property/IconHpMax.png');
|
||||
}
|
||||
&.ice {
|
||||
background-image: url('../images/property/IconIce.png');
|
||||
}
|
||||
&.penratio {
|
||||
background-image: url('../images/property/IconPenRatio.png');
|
||||
}
|
||||
&.penvalue {
|
||||
background-image: url('../images/property/IconPenValue.png');
|
||||
}
|
||||
&.physdmg {
|
||||
background-image: url('../images/property/IconPhysDmg.png');
|
||||
}
|
||||
&.spgetratio {
|
||||
background-image: url('../images/property/IconSpGetRatio.png');
|
||||
}
|
||||
&.spmax {
|
||||
background-image: url('../images/property/IconSpMax.png');
|
||||
}
|
||||
&.sprecover {
|
||||
background-image: url('../images/property/IconSpRecover.png');
|
||||
}
|
||||
&.thunder {
|
||||
background-image: url('../images/property/IconThunder.png');
|
||||
}
|
||||
}
|
||||
|
||||
.pro-icon {
|
||||
aspect-ratio: 1;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
&.anomaly {
|
||||
background-image: url('../images/prop/IconAnomaly.png');
|
||||
}
|
||||
&.attack {
|
||||
background-image: url('../images/prop/IconAttack.png');
|
||||
}
|
||||
&.defense {
|
||||
background-image: url('../images/prop/IconDefence.png');
|
||||
}
|
||||
&.stun {
|
||||
background-image: url('../images/prop/IconStun.png');
|
||||
}
|
||||
&.support {
|
||||
background-image: url('../images/prop/IconSupport.png');
|
||||
}
|
||||
}
|
||||
|
||||
.special-title {
|
||||
width: 100%;
|
||||
background-size: contain;
|
||||
|
|
|
|||
|
|
@ -7,80 +7,54 @@
|
|||
{{block 'main'}}
|
||||
<div class="card">
|
||||
{{include sys.playerInfo}}
|
||||
<div class="special-title">
|
||||
<div class="bg-content">
|
||||
STAMINA
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
电池电量
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="battery">
|
||||
<div class="icon">
|
||||
<img src="{{@sys.currentPath}}/images/IconStamina.png" alt="">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="bvalue">
|
||||
<div class="title">电量</div>
|
||||
<div class="value"><span class="big">{{note.energy.progress.current}}</span>/{{note.energy.progress.max}}</div>
|
||||
<% include(sys.specialTitle, {en: 'STAMINA' , cn: '电池电量' }) %>
|
||||
<div class="battery">
|
||||
<div class="icon">
|
||||
<img src="{{@sys.currentPath}}/images/IconStamina.png" alt="">
|
||||
</div>
|
||||
<div class="bleft">
|
||||
<div class="title">剩余</div>
|
||||
<div class="value">{{note.energy.progress.rest}}</div>
|
||||
</div>
|
||||
<div class="texture">
|
||||
<div class="bar">
|
||||
<div class="progress" style="width: {{note.energy.progress.percent}}%;"></div>
|
||||
<div class="info">
|
||||
<div class="bvalue">
|
||||
<div class="title">电量</div>
|
||||
<div class="value"><span class="big">{{note.energy.progress.current}}</span>/{{note.energy.progress.max}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="bleft">
|
||||
<div class="title">剩余</div>
|
||||
<div class="value">{{note.energy.progress.rest}}</div>
|
||||
</div>
|
||||
<div class="texture">
|
||||
<div class="bar">
|
||||
<div class="progress" style="width: {{note.energy.progress.percent}}%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="special-title">
|
||||
<div class="bg-content">
|
||||
ACTIVE
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
<div class="content">
|
||||
每日情况
|
||||
</div>
|
||||
<div class="parallelograms">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="active-list">
|
||||
<div class="active">
|
||||
<div class="status {{note.vitality.finish && 'finish'}}"></div>
|
||||
<div class="title">今日活跃度</div>
|
||||
<div class="value">
|
||||
{{note.vitality.current}}
|
||||
<span class="sub">/{{note.vitality.max}}</span>
|
||||
<% include(sys.specialTitle, {en: 'ACTIVE' , cn: '每日情况' }) %>
|
||||
<div class="active-list">
|
||||
<div class="active">
|
||||
<div class="status {{note.vitality.finish && 'finish'}}"></div>
|
||||
<div class="title">今日活跃度</div>
|
||||
<div class="value">
|
||||
{{note.vitality.current}}
|
||||
<span class="sub">/{{note.vitality.max}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="active">
|
||||
<div class="status {{note.vhs_sale.state && 'finish'}}"></div>
|
||||
<div class="title">录像店经营</div>
|
||||
<div class="value">
|
||||
{{note.vhs_sale.state_label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="active">
|
||||
<div class="status {{note.sign && 'finish'}}"></div>
|
||||
<div class="title">刮刮卡</div>
|
||||
<div class="value">
|
||||
{{note.sign_label}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="active">
|
||||
<div class="status {{note.vhs_sale.state && 'finish'}}"></div>
|
||||
<div class="title">录像店经营</div>
|
||||
<div class="value">
|
||||
{{note.vhs_sale.state_label}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="active">
|
||||
<div class="status {{note.sign && 'finish'}}"></div>
|
||||
<div class="title">刮刮卡</div>
|
||||
<div class="value">
|
||||
{{note.sign_label}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/block}}
|
||||
592
resources/panel/card.css
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
.card {
|
||||
padding-top: 0.8em;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card .star {
|
||||
width: 5.5em;
|
||||
height: 1.5em;
|
||||
}
|
||||
.card .star.star0 {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url("./images/star/0.png");
|
||||
}
|
||||
.card .star.star1 {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url("./images/star/1.png");
|
||||
}
|
||||
.card .star.star2 {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url("./images/star/2.png");
|
||||
}
|
||||
.card .star.star3 {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url("./images/star/3.png");
|
||||
}
|
||||
.card .star.star4 {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url("./images/star/4.png");
|
||||
}
|
||||
.card .star.star5 {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url("./images/star/5.png");
|
||||
}
|
||||
.card .basic {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card .basic .char {
|
||||
width: 55%;
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.card .basic .char .avatar {
|
||||
height: 100%;
|
||||
padding-top: 1em;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card .basic .char .avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: top center;
|
||||
position: absolute;
|
||||
}
|
||||
.card .basic .char .skills {
|
||||
position: absolute;
|
||||
width: 120%;
|
||||
height: 3.5em;
|
||||
background: url("./images/skill_bg.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
bottom: 3em;
|
||||
right: -1.6em;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding-left: 2.5em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
.card .basic .char .skills .skill {
|
||||
width: 1.4em;
|
||||
aspect-ratio: 1;
|
||||
margin-right: 1.38em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.card .basic .info {
|
||||
width: 45%;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
font-size: 1.2em;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.card .basic .info .char_info {
|
||||
width: 140%;
|
||||
position: relative;
|
||||
right: 20%;
|
||||
padding: 0.3em 0.2em;
|
||||
padding-right: 20%;
|
||||
padding-left: 8%;
|
||||
border-image-slice: 0 30 0 40 fill;
|
||||
border-image-width: 0em 1.5em 0em 2em;
|
||||
border-image-outset: 0 0 0 0;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url("./images/CurseBG04.png");
|
||||
filter: drop-shadow(0 0 0.1em rgb(0, 0, 0));
|
||||
}
|
||||
.card .basic .info .char_info .base {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.2em;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card .basic .info .char_info .base .rank {
|
||||
width: 1.2em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.card .basic .info .char_info .base .property {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.card .basic .info .char_info .base .name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.card .basic .info .char_info .addition {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.7em;
|
||||
gap: 0.2em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
.card .basic .info .char_info .addition .level {
|
||||
background-color: #000;
|
||||
padding: 0em 0.7em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks {
|
||||
display: flex;
|
||||
gap: 0.1em;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span {
|
||||
width: 1.2em;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 1em;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(1) {
|
||||
background-image: url("./images/ranks/1.png");
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r1 span:nth-child(1) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(2) {
|
||||
background-image: url("./images/ranks/2.png");
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r2 span:nth-child(1) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r2 span:nth-child(2) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(3) {
|
||||
background-image: url("./images/ranks/3.png");
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r3 span:nth-child(1) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r3 span:nth-child(2) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r3 span:nth-child(3) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(4) {
|
||||
background-image: url("./images/ranks/4.png");
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r4 span:nth-child(1) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r4 span:nth-child(2) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r4 span:nth-child(3) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r4 span:nth-child(4) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(5) {
|
||||
background-image: url("./images/ranks/5.png");
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r5 span:nth-child(1) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r5 span:nth-child(2) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r5 span:nth-child(3) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r5 span:nth-child(4) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r5 span:nth-child(5) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(6) {
|
||||
background-image: url("./images/ranks/6.png");
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(1) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(2) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(3) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(4) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(5) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r6 span:nth-child(6) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks span:nth-child(7) {
|
||||
background-image: url("./images/ranks/7.png");
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(1) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(2) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(3) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(4) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(5) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(6) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .char_info .addition .role_ranks.r7 span:nth-child(7) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.card .basic .info .property_info {
|
||||
background-color: rgb(47, 47, 47);
|
||||
border-left: 0.1em solid rgb(0, 0, 0);
|
||||
padding-top: 0.2em;
|
||||
background: url("./images/BgFrame01.png") center/150% no-repeat;
|
||||
}
|
||||
.card .basic .info .property_info .title {
|
||||
font-size: 0.6em;
|
||||
}
|
||||
.card .basic .info .property_info .title .special-title {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.card .basic .info .property_info .list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
.card .basic .info .property_info .list .properties {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4em;
|
||||
padding: 0.05em 1em 0em 0.05em;
|
||||
}
|
||||
.card .basic .info .property_info .list .properties:nth-child(odd) {
|
||||
background-color: rgba(221, 224, 221, 0.25);
|
||||
}
|
||||
.card .basic .info .property_info .list .properties .prop-icon {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
margin: 0 0.4em;
|
||||
}
|
||||
.card .basic .info .property_info .list .properties .label {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
font-size: 0.65em;
|
||||
color: rgb(166, 166, 166);
|
||||
}
|
||||
.card .basic .info .property_info .list .properties .label.yellow {
|
||||
color: rgb(247, 199, 54);
|
||||
}
|
||||
.card .basic .info .property_info .list .properties .label.blue {
|
||||
color: rgb(65, 147, 237);
|
||||
}
|
||||
.card .basic .info .property_info .list .properties .value {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.card .basic .info .weapon_info {
|
||||
border-image-slice: 118 0 68 43 fill;
|
||||
border-image-width: 4.5em 0em 2.7em 1.7em;
|
||||
border-image-outset: 0em 0em 0em 0em;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url("./images/weapon_bg.png");
|
||||
margin-top: -0.8em;
|
||||
width: 115%;
|
||||
margin-left: -15%;
|
||||
font-size: 0.8em;
|
||||
padding: 2em 1.2em;
|
||||
padding-bottom: 3em;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card .basic .info .weapon_info .info {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.card .basic .info .weapon_info .info .base {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
}
|
||||
.card .basic .info .weapon_info .info .base .rarity-icon {
|
||||
width: 2em;
|
||||
}
|
||||
.card .basic .info .weapon_info .info .base .name {
|
||||
text-shadow: 0 0 0.2em rgb(0, 0, 0);
|
||||
}
|
||||
.card .basic .info .weapon_info .info .main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
width: max-content;
|
||||
}
|
||||
.card .basic .info .weapon_info .info .main .addition {
|
||||
font-size: 0.8em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4em;
|
||||
}
|
||||
.card .basic .info .weapon_info .info .main .addition .level {
|
||||
-webkit-clip-path: polygon(0.2em 0%, calc(100% - 0.2em) 0%, 100% 0.2em, 100% calc(100% - 0.2em), calc(100% - 0.2em) 100%, 0.2em 100%, 0% calc(100% - 0.2em), 0% 0.2em);
|
||||
clip-path: polygon(0.2em 0%, calc(100% - 0.2em) 0%, 100% 0.2em, 100% calc(100% - 0.2em), calc(100% - 0.2em) 100%, 0.2em 100%, 0% calc(100% - 0.2em), 0% 0.2em);
|
||||
padding: 0 0.4em;
|
||||
font-size: 0.9em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: rgb(43, 38, 40);
|
||||
margin: 0.1em 0;
|
||||
background-color: rgb(243, 203, 69);
|
||||
}
|
||||
.card .basic .info .weapon_info .info .main .properties {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: rgb(65, 147, 237);
|
||||
gap: 0.2em;
|
||||
padding: 0 0.5em;
|
||||
border-radius: 1em;
|
||||
margin: 0.2em 0;
|
||||
}
|
||||
.card .basic .info .weapon_info .info .main .properties.sub {
|
||||
background-color: rgb(0, 0, 0);
|
||||
}
|
||||
.card .basic .info .weapon_info .info .main .properties .prop-icon {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.card .basic .info .weapon_info .info .main .properties .label {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
font-size: 0.7em;
|
||||
color: rgb(222, 222, 222);
|
||||
}
|
||||
.card .basic .info .weapon_info .icon {
|
||||
position: absolute;
|
||||
top: 1.2em;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
height: 70%;
|
||||
margin-right: -1em;
|
||||
}
|
||||
.card .basic .info .weapon_info .icon img {
|
||||
height: 100%;
|
||||
}
|
||||
.card .other {
|
||||
border-image-source: url("./images/BgFrame01.png");
|
||||
border-image-slice: 200 100 70 280 fill;
|
||||
border-image-width: 2em 1em 0.7em 2.8em;
|
||||
border-image-outset: 2em 1em 0.7em 2.8em;
|
||||
border-image-repeat: stretch stretch;
|
||||
padding-bottom: 3.3em;
|
||||
margin-top: -1.4em;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
.card .equip-list {
|
||||
display: grid;
|
||||
gap: 1em;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
padding: 0 1.8em;
|
||||
align-items: stretch;
|
||||
margin-top: 1em;
|
||||
}
|
||||
.card .equip-list .box {
|
||||
border-image-source: url("./images/equip_bg.png");
|
||||
border-image-slice: 190 90 110 170 fill;
|
||||
border-image-width: 5.7em 2.7em 3.3em 5.1em;
|
||||
border-image-outset: 1.8em 1.5em 1.8em 1.5em;
|
||||
border-image-repeat: stretch stretch;
|
||||
position: relative;
|
||||
margin-top: 1.3em;
|
||||
padding-bottom: 1em;
|
||||
min-height: 10em;
|
||||
}
|
||||
.card .equip-list .box.empty::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-image: url("./images/empty_equip_07.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
.card .equip-list .box:nth-child(1)::before {
|
||||
content: "01";
|
||||
position: absolute;
|
||||
font-size: 2em;
|
||||
left: 50%;
|
||||
top: -0.85em;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
.card .equip-list .box:nth-child(2)::before {
|
||||
content: "02";
|
||||
position: absolute;
|
||||
font-size: 2em;
|
||||
left: 50%;
|
||||
top: -0.85em;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
.card .equip-list .box:nth-child(3)::before {
|
||||
content: "03";
|
||||
position: absolute;
|
||||
font-size: 2em;
|
||||
left: 50%;
|
||||
top: -0.85em;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
.card .equip-list .box:nth-child(4)::before {
|
||||
content: "04";
|
||||
position: absolute;
|
||||
font-size: 2em;
|
||||
left: 50%;
|
||||
top: -0.85em;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
.card .equip-list .box:nth-child(5)::before {
|
||||
content: "05";
|
||||
position: absolute;
|
||||
font-size: 2em;
|
||||
left: 50%;
|
||||
top: -0.85em;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
.card .equip-list .box:nth-child(6)::before {
|
||||
content: "06";
|
||||
position: absolute;
|
||||
font-size: 2em;
|
||||
left: 50%;
|
||||
top: -0.85em;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
.card .equip-list .box .icon {
|
||||
width: 2.7em;
|
||||
aspect-ratio: 1;
|
||||
position: relative;
|
||||
left: -0.9em;
|
||||
top: -1.2em;
|
||||
background-color: rgb(0, 0, 0);
|
||||
background-image: url("./images/empty_equip_03.png");
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.card .equip-list .box .icon img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
.card .equip-list .box .info {
|
||||
display: flex;
|
||||
padding-left: 2.2em;
|
||||
margin-top: -2.5em;
|
||||
gap: 0.5em;
|
||||
align-items: center;
|
||||
}
|
||||
.card .equip-list .box .info .level {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
text-align: center;
|
||||
font-size: 0.76em;
|
||||
background-color: #000;
|
||||
padding: 0.1em 0.5em;
|
||||
border-radius: 1em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
.card .equip-list .box .info .rarity-icon {
|
||||
width: 2.2em;
|
||||
}
|
||||
.card .equip-list .box .name {
|
||||
padding: 0 0.5em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
.card .equip-list .box .property-list {
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
.card .equip-list .box .property-list .properties {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: rgb(0, 0, 0);
|
||||
gap: 0.2em;
|
||||
padding: 0 0.5em;
|
||||
border-radius: 1em;
|
||||
margin: 0.2em 0;
|
||||
}
|
||||
.card .equip-list .box .property-list .properties .prop-icon {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.card .equip-list .box .property-list .properties .label {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
font-size: 0.7em;
|
||||
color: rgb(222, 222, 222);
|
||||
}
|
||||
.card .equip-list .box .property-list .properties .value {
|
||||
color: rgb(249, 189, 64);
|
||||
font-size: 0.7em;
|
||||
}
|
||||
.card .equip-list .box .property-list .properties.main {
|
||||
background-color: rgb(65, 147, 237);
|
||||
}
|
||||
.card .equip-list .box .property-list .properties.main .prop-icon {
|
||||
width: 1.2em;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
.card .equip-list .box .property-list .properties.main .value {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.copyright {
|
||||
margin-top: -3.3em;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=card.css.map */
|
||||
178
resources/panel/card.html
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
{{extend defaultLayout}}
|
||||
|
||||
{{block 'css'}}
|
||||
<link rel="stylesheet" href="{{@sys.currentPath}}/card.css">
|
||||
{{/block}}
|
||||
|
||||
{{block 'main'}}
|
||||
<div class="card">
|
||||
<div class="basic">
|
||||
<div class="char">
|
||||
<div class="avatar">
|
||||
<img src="{{charData.role_icon}}" alt="">
|
||||
</div>
|
||||
<div class="skills">
|
||||
{{each charData.skills skill}}
|
||||
<div class="skill">{{skill.level}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="char_info">
|
||||
<div class="base">
|
||||
<div class="rank rank-icon {{charData.rarity}}"></div>
|
||||
<div class="property {{charData.element_str}}"></div>
|
||||
<div class="name">{{charData.full_name_mi18n}}</div>
|
||||
</div>
|
||||
<div class="addition">
|
||||
<div class="level">Lv.{{charData.level}}</div>
|
||||
<div class="role_ranks r{{charData.rank}}">
|
||||
<span></span><span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="property_info">
|
||||
<div class="title">
|
||||
<% include(sys.specialTitle, {en: 'PROPERTY' , cn: '属性' , count: 6 }) %>
|
||||
</div>
|
||||
<div class="list">
|
||||
<div class="properties">
|
||||
<div class="prop-icon hpmax"></div>
|
||||
<div class="label yellow">生命值</div>
|
||||
<div class="value">{{charData.basic_properties.hpmax.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon attack"></div>
|
||||
<div class="label yellow">攻击力</div>
|
||||
<div class="value">{{charData.basic_properties.attack.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon def"></div>
|
||||
<div class="label yellow">防御力</div>
|
||||
<div class="value">{{charData.basic_properties.def.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon breakstun"></div>
|
||||
<div class="label">冲击力</div>
|
||||
<div class="value">{{charData.basic_properties.breakstun.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon crit"></div>
|
||||
<div class="label blue">暴击率</div>
|
||||
<div class="value">{{charData.basic_properties.crit.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon critdam"></div>
|
||||
<div class="label blue">暴击伤害</div>
|
||||
<div class="value">{{charData.basic_properties.critdam.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon elementabnormalpower"></div>
|
||||
<div class="label">异常掌控</div>
|
||||
<div class="value">{{charData.basic_properties.elementabnormalpower.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon elementmystery"></div>
|
||||
<div class="label">异常精通</div>
|
||||
<div class="value">{{charData.basic_properties.elementmystery.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon penratio"></div>
|
||||
<div class="label">穿透率</div>
|
||||
<div class="value">{{charData.basic_properties.penratio.final}}</div>
|
||||
</div>
|
||||
<div class="properties">
|
||||
<div class="prop-icon sprecover"></div>
|
||||
<div class="label">能量恢复</div>
|
||||
<div class="value">{{charData.basic_properties.sprecover.final}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weapon_info">
|
||||
{{if charData.weapon}}
|
||||
<div class="info">
|
||||
<div class="base">
|
||||
<div class="rarity-icon {{charData.weapon.rarity}}"></div>
|
||||
<div class="name">{{charData.weapon.name}}</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="addition">
|
||||
<div class="star star{{charData.weapon.star}}"></div>
|
||||
<div class="level">Lv.{{charData.weapon.level}}</div>
|
||||
</div>
|
||||
{{each charData.weapon.main_properties prop}}
|
||||
<div class="properties">
|
||||
<div class="prop-icon {{prop.classname}}"></div>
|
||||
<div class="label">{{prop.property_name}}</div>
|
||||
<div class="value">{{prop.base}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{each charData.weapon.properties prop}}
|
||||
<div class="properties sub">
|
||||
<div class="prop-icon {{prop.classname}}"></div>
|
||||
<div class="label">{{prop.property_name}}</div>
|
||||
<div class="value">{{prop.base}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="icon">
|
||||
<img src="{{charData.weapon.square_icon}}" alt="">
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="info empty">
|
||||
<div class="base">
|
||||
<div class="rarity-icon"></div>
|
||||
<div class="name"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="other">
|
||||
<div class="title">
|
||||
<% include(sys.specialTitle, {en: 'METAL' , cn: '驱动盘信息' }) %>
|
||||
</div>
|
||||
<div class="equip-list">
|
||||
{{each charData.equip equip}}
|
||||
<div class="box">
|
||||
<div class="icon">
|
||||
<img src="{{equip.suit_icon}}" alt="">
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="level">等级{{equip.level}}</div>
|
||||
<div class="rarity-icon {{equip.rarity}}"></div>
|
||||
</div>
|
||||
<div class="name">{{equip.name}}</div>
|
||||
<div class="property-list">
|
||||
|
||||
{{each equip.main_properties prop}}
|
||||
<div class="properties main">
|
||||
<div class="prop-icon {{prop.classname}}"></div>
|
||||
<div class="label yellow">{{prop.property_name}}</div>
|
||||
<div class="value">{{prop.base}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
||||
{{each equip.properties prop}}
|
||||
<div class="properties">
|
||||
<div class="prop-icon {{prop.classname}}"></div>
|
||||
<div class="label yellow">{{prop.property_name}}</div>
|
||||
<div class="value">{{prop.base}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
<% for(let i=charData.equip.length; i < 6 ; i++) { %>
|
||||
<div class="box empty">
|
||||
<div class="icon">
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/block}}
|
||||
449
resources/panel/card.scss
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
.card {
|
||||
padding-top: 0.8em;
|
||||
overflow: hidden;
|
||||
.star {
|
||||
width: 5.5em;
|
||||
height: 1.5em;
|
||||
@for $i from 0 through 5 {
|
||||
&.star#{$i} {
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url('./images/star/#{$i}.png');
|
||||
}
|
||||
}
|
||||
}
|
||||
.basic {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
.char {
|
||||
width: 55%;
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
.avatar {
|
||||
height: 100%;
|
||||
padding-top: 1em;
|
||||
overflow: hidden;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: top center;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
.skills {
|
||||
position: absolute;
|
||||
width: 120%;
|
||||
height: 3.5em;
|
||||
background: url('./images/skill_bg.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
bottom: 3em;
|
||||
right: -1.6em;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding-left: 2.5em;
|
||||
padding-bottom: 0.2em;
|
||||
.skill {
|
||||
width: 1.4em;
|
||||
aspect-ratio: 1;
|
||||
margin-right: 1.38em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.info {
|
||||
width: 45%;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
font-size: 1.2em;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
.char_info {
|
||||
width: 140%;
|
||||
position: relative;
|
||||
right: 20%;
|
||||
padding: 0.3em 0.2em;
|
||||
padding-right: 20%;
|
||||
padding-left: 8%;
|
||||
border-image-slice: 0 30 0 40 fill;
|
||||
border-image-width: 0em 1.5em 0em 2em;
|
||||
border-image-outset: 0 0 0 0;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url('./images/CurseBG04.png');
|
||||
filter: drop-shadow(0 0 0.1em rgb(0, 0, 0));
|
||||
.base {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.2em;
|
||||
overflow: hidden;
|
||||
.rank {
|
||||
width: 1.2em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.property {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.addition {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 0.7em;
|
||||
gap: 0.2em;
|
||||
padding-left: 1em;
|
||||
.level {
|
||||
background-color: #000;
|
||||
padding: 0em 0.7em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
.role_ranks {
|
||||
display: flex;
|
||||
gap: 0.1em;
|
||||
span {
|
||||
width: 1.2em;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 1em;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
opacity: 0.4;
|
||||
}
|
||||
@for $i from 1 through 7 {
|
||||
span:nth-child(#{$i}) {
|
||||
background-image: url('./images/ranks/#{$i}.png');
|
||||
}
|
||||
&.r#{$i} {
|
||||
@for $j from 1 through $i {
|
||||
span:nth-child(#{$j}) {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.property_info {
|
||||
background-color: rgb(47, 47, 47);
|
||||
border-left: 0.1em solid rgb(0, 0, 0);
|
||||
padding-top: 0.2em;
|
||||
background: url('./images/BgFrame01.png') center / 150% no-repeat;
|
||||
.title {
|
||||
font-size: 0.6em;
|
||||
.special-title {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
.properties {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4em;
|
||||
padding: 0.05em 1em 0em 0.05em;
|
||||
&:nth-child(odd) {
|
||||
background-color: rgba(221, 224, 221, 0.25);
|
||||
}
|
||||
.prop-icon {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
margin: 0 0.4em;
|
||||
}
|
||||
.label {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
font-size: 0.65em;
|
||||
color: rgb(166, 166, 166);
|
||||
&.yellow {
|
||||
color: rgb(247, 199, 54);
|
||||
}
|
||||
&.blue {
|
||||
color: rgb(65, 147, 237);
|
||||
}
|
||||
}
|
||||
.value {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.weapon_info {
|
||||
border-image-slice: 118 0 68 43 fill;
|
||||
border-image-width: 4.5em 0em 2.7em 1.7em;
|
||||
border-image-outset: 0em 0em 0em 0em;
|
||||
border-image-repeat: stretch stretch;
|
||||
border-image-source: url('./images/weapon_bg.png');
|
||||
margin-top: -0.8em;
|
||||
width: 115%;
|
||||
margin-left: -15%;
|
||||
font-size: 0.8em;
|
||||
padding: 2em 1.2em;
|
||||
padding-bottom: 3em;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
.info {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
.base {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
.rarity-icon {
|
||||
width: 2em;
|
||||
}
|
||||
.name {
|
||||
text-shadow: 0 0 0.2em rgb(0, 0, 0);
|
||||
}
|
||||
}
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: stretch;
|
||||
width: max-content;
|
||||
.addition {
|
||||
font-size: 0.8em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4em;
|
||||
.level {
|
||||
$label-width: 0.2em;
|
||||
-webkit-clip-path: polygon(
|
||||
$label-width 0%,
|
||||
calc(100% - $label-width) 0%,
|
||||
100% $label-width,
|
||||
100% calc(100% - $label-width),
|
||||
calc(100% - $label-width) 100%,
|
||||
$label-width 100%,
|
||||
0% calc(100% - $label-width),
|
||||
0% $label-width
|
||||
);
|
||||
clip-path: polygon(
|
||||
$label-width 0%,
|
||||
calc(100% - $label-width) 0%,
|
||||
100% $label-width,
|
||||
100% calc(100% - $label-width),
|
||||
calc(100% - $label-width) 100%,
|
||||
$label-width 100%,
|
||||
0% calc(100% - $label-width),
|
||||
0% $label-width
|
||||
);
|
||||
padding: 0 0.4em;
|
||||
font-size: 0.9em;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: rgb(43, 38, 40);
|
||||
margin: 0.1em 0;
|
||||
background-color: rgb(243, 203, 69);
|
||||
}
|
||||
}
|
||||
.properties {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: rgb(65, 147, 237);
|
||||
gap: 0.2em;
|
||||
padding: 0 0.5em;
|
||||
border-radius: 1em;
|
||||
margin: 0.2em 0;
|
||||
&.sub {
|
||||
background-color: rgb(0, 0, 0);
|
||||
}
|
||||
.prop-icon {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.label {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
font-size: 0.7em;
|
||||
color: rgb(222, 222, 222);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon {
|
||||
position: absolute;
|
||||
top: 1.2em;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
height: 70%;
|
||||
margin-right: -1em;
|
||||
img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.other {
|
||||
border-image-source: url('./images/BgFrame01.png');
|
||||
border-image-slice: 200 100 70 280 fill;
|
||||
border-image-width: 2em 1em 0.7em 2.8em;
|
||||
border-image-outset: 2em 1em 0.7em 2.8em;
|
||||
border-image-repeat: stretch stretch;
|
||||
padding-bottom: 3.3em;
|
||||
margin-top: -1.4em;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
.equip-list {
|
||||
display: grid;
|
||||
gap: 1em;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
padding: 0 1.8em;
|
||||
align-items: stretch;
|
||||
margin-top: 1em;
|
||||
.box {
|
||||
$size: 3em;
|
||||
border-image-source: url('./images/equip_bg.png');
|
||||
border-image-slice: 190 90 110 170 fill;
|
||||
border-image-width: 1.9 * $size 0.9 * $size 1.1 * $size 1.7 * $size;
|
||||
border-image-outset: 0.6 * $size 0.5 * $size 0.6 * $size 0.5 * $size;
|
||||
border-image-repeat: stretch stretch;
|
||||
position: relative;
|
||||
margin-top: 1.3em;
|
||||
padding-bottom: 1em;
|
||||
min-height: 10em;
|
||||
&.empty {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background-image: url('./images/empty_equip_07.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
}
|
||||
@for $i from 1 through 6 {
|
||||
&:nth-child(#{$i}) {
|
||||
&::before {
|
||||
content: '0#{$i}';
|
||||
position: absolute;
|
||||
font-size: 2em;
|
||||
left: 50%;
|
||||
top: -0.85em;
|
||||
transform: translate(-50%, 0);
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
.icon {
|
||||
width: 0.9 * $size;
|
||||
aspect-ratio: 1;
|
||||
position: relative;
|
||||
left: -0.3 * $size;
|
||||
top: -0.4 * $size;
|
||||
background-color: rgb(0, 0, 0);
|
||||
background-image: url('./images/empty_equip_03.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
border-radius: 50%;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.info {
|
||||
display: flex;
|
||||
padding-left: 2.2em;
|
||||
margin-top: -2.5em;
|
||||
gap: 0.5em;
|
||||
align-items: center;
|
||||
.level {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
text-align: center;
|
||||
font-size: 0.76em;
|
||||
background-color: #000;
|
||||
padding: 0.1em 0.5em;
|
||||
border-radius: 1em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
.rarity-icon {
|
||||
width: 2.2em;
|
||||
}
|
||||
}
|
||||
.name {
|
||||
padding: 0 0.5em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
}
|
||||
.property-list {
|
||||
padding: 0 0.5em;
|
||||
.properties {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: rgb(0, 0, 0);
|
||||
gap: 0.2em;
|
||||
padding: 0 0.5em;
|
||||
border-radius: 1em;
|
||||
margin: 0.2em 0;
|
||||
.prop-icon {
|
||||
width: 1em;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.label {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
font-size: 0.7em;
|
||||
color: rgb(222, 222, 222);
|
||||
}
|
||||
.value {
|
||||
color: rgb(249, 189, 64);
|
||||
font-size: 0.7em;
|
||||
}
|
||||
&.main {
|
||||
background-color: rgb(65, 147, 237);
|
||||
.prop-icon {
|
||||
width: 1.2em;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
.value {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.copyright {
|
||||
margin-top: -3.3em;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
BIN
resources/panel/images/BgFrame01.png
Normal file
|
After Width: | Height: | Size: 996 KiB |
BIN
resources/panel/images/CurseBG04.png
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
resources/panel/images/GroceryActivityBtnBg.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
resources/panel/images/empty_equip_03.png
Normal file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
resources/panel/images/empty_equip_07.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/panel/images/equip_bg.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
resources/panel/images/ranks/1.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/panel/images/ranks/2.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/panel/images/ranks/3.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/panel/images/ranks/4.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/panel/images/ranks/5.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/panel/images/ranks/6.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/panel/images/skill_bg.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
resources/panel/images/star/0.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
resources/panel/images/star/1.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
resources/panel/images/star/2.png
Normal file
|
After Width: | Height: | Size: 4 KiB |
BIN
resources/panel/images/star/3.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
resources/panel/images/star/4.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
resources/panel/images/star/5.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
resources/panel/images/weapon_bg.png
Normal file
|
After Width: | Height: | Size: 17 KiB |