整理资源

master
humingxing 4 days ago
parent ddcb581ab3
commit f8bf0c4bbf
  1. 2
      assets/bundles/popBattle/popSelect.meta
  2. 2
      assets/bundles/popBattle/popSelect/prefab.meta
  3. 272
      assets/res/popBattle/SkillSelect/spine/选择框.atlas
  4. 12
      assets/res/popBattle/SkillSelect/spine/选择框.atlas.meta
  5. 1
      assets/res/popBattle/SkillSelect/spine/选择框.json
  6. 13
      assets/res/popBattle/SkillSelect/spine/选择框.json.meta
  7. BIN
      assets/res/popBattle/SkillSelect/spine/选择框.png
  8. 134
      assets/res/popBattle/SkillSelect/spine/选择框.png.meta
  9. 9
      assets/res/popBattle/popSelect.meta
  10. 2
      assets/res/popBattle/popSelect/texture.meta
  11. 6
      assets/script/battle/combat/TowerLoadoutService.ts
  12. 42
      assets/script/battle/combat/TowerStatResolver.ts
  13. 9
      assets/script/battle/view/CocosBagBoardView.ts
  14. 23
      assets/script/game/ConfigProjectData.ts
  15. 3
      assets/script/ui/BattleGame/BattleGameRewriteGlyphPresenter.ts
  16. 4
      assets/script/ui/BattleGame/Monster.ts

@ -2,7 +2,7 @@
"ver": "1.2.0", "ver": "1.2.0",
"importer": "directory", "importer": "directory",
"imported": true, "imported": true,
"uuid": "95f22647-b7cb-4fca-ab68-e7b6519b1ea7", "uuid": "e8af14ca-74b3-48ea-8912-fec3ea86b266",
"files": [], "files": [],
"subMetas": {}, "subMetas": {},
"userData": {} "userData": {}

@ -2,7 +2,7 @@
"ver": "1.2.0", "ver": "1.2.0",
"importer": "directory", "importer": "directory",
"imported": true, "imported": true,
"uuid": "d05c836a-de42-455c-b77f-96842b83d906", "uuid": "75ff3460-ff8b-4900-a885-bef85187cc49",
"files": [], "files": [],
"subMetas": {}, "subMetas": {},
"userData": {} "userData": {}

@ -1,272 +0,0 @@
选择框.png
size: 1943,1792
format: RGBA8888
filter: Linear,Linear
repeat: none
bai
rotate: true
xy: 383, 15
size: 205, 381
orig: 207, 383
offset: 1, 1
index: -1
橙色阶
rotate: true
xy: 0, 13
size: 207, 381
orig: 207, 383
offset: 0, 1
index: -1
橙色阶_00000
rotate: false
xy: 0, 1401
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00001
rotate: false
xy: 0, 1008
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00002
rotate: false
xy: 0, 615
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00003
rotate: false
xy: 0, 222
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00004
rotate: false
xy: 252, 1401
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00005
rotate: false
xy: 252, 1008
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00006
rotate: false
xy: 252, 615
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00007
rotate: false
xy: 252, 222
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00008
rotate: true
xy: 766, 1542
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00009
rotate: false
xy: 504, 1401
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00010
rotate: true
xy: 1159, 1542
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00011
rotate: true
xy: 1552, 1542
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00012
rotate: true
xy: 756, 1290
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00013
rotate: false
xy: 504, 1008
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
橙色阶_00014
rotate: false
xy: 504, 615
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
祥云
rotate: false
xy: 1512, 529
size: 94, 48
orig: 94, 48
offset: 0, 0
index: -1
紫星星
rotate: false
xy: 1552, 12
size: 75, 105
orig: 77, 107
offset: 1, 1
index: -1
紫色阶
rotate: true
xy: 1552, 119
size: 201, 375
orig: 201, 377
offset: 0, 1
index: -1
紫色阶_00000
rotate: false
xy: 504, 222
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00001
rotate: true
xy: 1149, 1290
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00002
rotate: true
xy: 1542, 1290
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00003
rotate: false
xy: 756, 897
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00004
rotate: false
xy: 756, 504
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00005
rotate: true
xy: 756, 252
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00006
rotate: true
xy: 766, 0
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00007
rotate: false
xy: 1008, 897
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00008
rotate: false
xy: 1008, 504
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00009
rotate: true
xy: 1149, 252
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00010
rotate: true
xy: 1159, 0
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00011
rotate: true
xy: 1542, 1038
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00012
rotate: false
xy: 1260, 897
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00013
rotate: true
xy: 1512, 786
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
紫色阶_00014
rotate: false
xy: 1260, 504
size: 250, 391
orig: 250, 391
offset: 0, 0
index: -1
绿色阶
rotate: true
xy: 1542, 322
size: 205, 378
orig: 207, 380
offset: 1, 1
index: -1
蓝色阶
rotate: true
xy: 1512, 579
size: 205, 379
orig: 207, 381
offset: 1, 1
index: -1
黄星星
rotate: false
xy: 1629, 12
size: 75, 105
orig: 77, 107
offset: 1, 1
index: -1

@ -1,12 +0,0 @@
{
"ver": "1.0.0",
"importer": "*",
"imported": true,
"uuid": "60bb1b87-8182-4df5-8fd2-84c12d34b624",
"files": [
".atlas",
".json"
],
"subMetas": {},
"userData": {}
}

File diff suppressed because one or more lines are too long

@ -1,13 +0,0 @@
{
"ver": "1.2.7",
"importer": "spine-data",
"imported": true,
"uuid": "6dce4e3c-5cd9-4abb-bfd5-27ae8cb0b2a7",
"files": [
".json"
],
"subMetas": {},
"userData": {
"atlasUuid": "60bb1b87-8182-4df5-8fd2-84c12d34b624"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

@ -1,134 +0,0 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "d436042b-a21c-45c9-86cf-8cdec08c94d0",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "d436042b-a21c-45c9-86cf-8cdec08c94d0@6c48a",
"displayName": "选择框",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "d436042b-a21c-45c9-86cf-8cdec08c94d0",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "d436042b-a21c-45c9-86cf-8cdec08c94d0@f9941",
"displayName": "选择框",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 1943,
"height": 1792,
"rawWidth": 1943,
"rawHeight": 1792,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-971.5,
-896,
0,
971.5,
-896,
0,
-971.5,
896,
0,
971.5,
896,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
0,
1792,
1943,
1792,
0,
0,
1943,
0
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
],
"minPos": [
-971.5,
-896,
0
],
"maxPos": [
971.5,
896,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "d436042b-a21c-45c9-86cf-8cdec08c94d0@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"hasAlpha": true,
"fixAlphaTransparencyArtifacts": false,
"redirect": "d436042b-a21c-45c9-86cf-8cdec08c94d0@6c48a"
}
}

@ -0,0 +1,9 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "701dcbb7-c268-49a5-b241-fd2cd67a6a92",
"files": [],
"subMetas": {},
"userData": {}
}

@ -2,7 +2,7 @@
"ver": "1.2.0", "ver": "1.2.0",
"importer": "directory", "importer": "directory",
"imported": true, "imported": true,
"uuid": "4081e53a-5ec5-46e1-be53-eaa951e0aa06", "uuid": "2543eb5b-839b-4195-a3e2-a046701d0820",
"files": [], "files": [],
"subMetas": {}, "subMetas": {},
"userData": {} "userData": {}

@ -99,14 +99,16 @@ export class TowerLoadoutService {
weaponSkillActive = Number(sk.type) === 1; weaponSkillActive = Number(sk.type) === 1;
} }
} }
// 五行每行自带技能数组;非五行仍按合成等级取下标
const skillLv = isElementHero(hero) ? 1 : level;
const loadout: TowerLoadout = { const loadout: TowerLoadout = {
weapon1Id: heroId, weapon1Id: heroId,
level, level,
weaponId, weaponId,
normalBaseAtkId: heroNormalSkillId(hero, level), normalBaseAtkId: heroNormalSkillId(hero, skillLv),
overAtkType: '', overAtkType: '',
overAtkPara: '', overAtkPara: '',
activeSkillBaseAtkId: heroUltSkillId(hero, level), activeSkillBaseAtkId: heroUltSkillId(hero, skillLv),
weaponSkillId, weaponSkillId,
weaponSkillActive, weaponSkillActive,
}; };

@ -70,6 +70,7 @@ export function resolveBaseAtkRangePx(baseAtk: ITableSkill | null): number {
} }
/** /**
* @deprecated 五行数字已按 Hero 分行取 atk,勿再乘本系数;仅旧非五行路径保留。
* 合成等级 → 攻击力等级系数(常量表 id=13 para1,按下标 level-1)。 * 合成等级 → 攻击力等级系数(常量表 id=13 para1,按下标 level-1)。
* @param composeLevel 有效合成等级(≥1) * @param composeLevel 有效合成等级(≥1)
*/ */
@ -124,35 +125,48 @@ function rangeAddFromAtkBuff(raw: string | undefined): number {
} }
/** /**
* 局内合成等级 → 战斗基础数值(不含局外角色攻击/暴击/冷却系数)。 * 局内战斗基础数值(不含局外角色攻击/暴击/冷却系数)。
* 实际攻击力 = Hero.atk × 等级系数 + 装备 atk(若有)。 * 五行:合成后已是独立 Hero 行,攻击力=该行 atk(+宝石),不再乘 Const 等级系数。
* @param w1 Hero 行 * @param w1 Hero 行(五行须已是目标等级那一行)
* @param composeLevel 合成等级 * @param composeLevel 显示/合成等级;五行仅作校验,攻击取 w1.atk
* @param battleWeaponId 战斗武器 id;AI/指定装载须传入,缺省才读本机 gg.equip * @param battleWeaponId 战斗武器 id;AI/指定装载须传入,缺省才读本机 gg.equip
*/ */
export function deriveTowerSetupStats(w1: ITableHero, composeLevel: number, battleWeaponId?: number): TowerSetupStats { export function deriveTowerSetupStats(w1: ITableHero, composeLevel: number, battleWeaponId?: number): TowerSetupStats {
const compose = Math.max(1, Math.floor(composeLevel) || 1); const compose = Math.max(1, Math.floor(composeLevel) || 1);
const weaponId = resolveSetupWeaponId(w1, battleWeaponId);
const weaponRow = weaponId > 0
? gg.data.table.getTableData<ITableWeapon>(TableNames.Weapon, weaponId)
: null;
const exclusiveMul = weaponRow ? gg.equip.getEquipExclusiveMul(w1.id, weaponRow) : 1;
const weaponAtk = (weaponRow?.atk ?? 0) * exclusiveMul;
let effectiveLevel: number; let effectiveLevel: number;
let levelCoef: number;
let attack: number;
let skillLevel: number;
if (isElementHero(w1)) { if (isElementHero(w1)) {
const rowLevel = Math.floor(Number(w1.level)) || 0;
const cap = WeaponComposeConfigProvider.instance.getElementMaxLevel(Math.floor(Number(w1.herotype))); const cap = WeaponComposeConfigProvider.instance.getElementMaxLevel(Math.floor(Number(w1.herotype)));
effectiveLevel = Math.min(compose, cap); effectiveLevel = rowLevel > 0 ? Math.min(rowLevel, cap) : Math.min(compose, cap);
if (rowLevel > 0 && rowLevel !== compose) {
console.warn('[TowerStatResolver] 五行 Hero.level 与传入等级不一致', w1.id, rowLevel, compose);
}
levelCoef = 1;
attack = w1.atk + weaponAtk;
// 每行自带 atk_id,按本行取技能(下标 0)
skillLevel = 1;
} else { } else {
if (!(w1.level_limit > 0)) { if (!(w1.level_limit > 0)) {
console.log('[TowerStatResolver] Hero.level_limit 未配置', w1.id); console.log('[TowerStatResolver] Hero.level_limit 未配置', w1.id);
} }
const levelLimit = w1.level_limit > 0 ? w1.level_limit : 1; const levelLimit = w1.level_limit > 0 ? w1.level_limit : 1;
effectiveLevel = Math.min(compose, levelLimit); effectiveLevel = Math.min(compose, levelLimit);
levelCoef = resolveAtkLevelCoef(effectiveLevel);
attack = w1.atk * levelCoef + weaponAtk;
skillLevel = effectiveLevel;
} }
const weaponId = resolveSetupWeaponId(w1, battleWeaponId);
const weaponRow = weaponId > 0
? gg.data.table.getTableData<ITableWeapon>(TableNames.Weapon, weaponId)
: null;
const exclusiveMul = weaponRow ? gg.equip.getEquipExclusiveMul(w1.id, weaponRow) : 1;
const weaponAtk = (weaponRow?.atk ?? 0) * exclusiveMul;
const levelCoef = resolveAtkLevelCoef(effectiveLevel);
const attack = w1.atk * levelCoef + weaponAtk;
const skillId = heroNormalSkillId(w1, effectiveLevel); const skillId = heroNormalSkillId(w1, skillLevel);
const skillRow = skillId > 0 ? gg.data.table.getTableData<ITableSkill>(TableNames.Skill, skillId) : null; const skillRow = skillId > 0 ? gg.data.table.getTableData<ITableSkill>(TableNames.Skill, skillId) : null;
const attackSpeed = skillRow?.cd > 0 ? 1 / skillRow.cd : 1; const attackSpeed = skillRow?.cd > 0 ? 1 / skillRow.cd : 1;
const critRate = Math.min(1, (w1.critical_chance ?? 0) / 10000); const critRate = Math.min(1, (w1.critical_chance ?? 0) / 10000);

@ -3468,6 +3468,7 @@ export class CocosBagBoardView {
grid.restoreOrigin(); grid.restoreOrigin();
} else { } else {
this._commitViewsAfterSuccessfulDrop(grid, target); this._commitViewsAfterSuccessfulDrop(grid, target);
this._tryPresentPendingAttrRewrite();
this._vibratePlaceSuccess(); this._vibratePlaceSuccess();
if (drag.source.kind === 'bag' && target.kind === 'map') { if (drag.source.kind === 'bag' && target.kind === 'map') {
bagAttackSpeedPlace = { source: drag.source, target }; bagAttackSpeedPlace = { source: drag.source, target };
@ -4489,6 +4490,11 @@ export class CocosBagBoardView {
this._requestBagRebuild(false); this._requestBagRebuild(false);
break; break;
} }
// 属性卡换五行会换 Hero.id:必须先 DeploySync 再刷视图/Skill,
// 否则 ensureNumberSkill 绑到旧实体,reconcile 销毁后数字停攻。
if (this._deploySync && this._map.gridsInitialized) {
this._deploySync.reconcileFromMerge('glyphRewritten');
}
if (this._applyMapGlyphRewriteInPlace(event.target.gridIndex)) { if (this._applyMapGlyphRewriteInPlace(event.target.gridIndex)) {
this._refreshCanUpgradeHints(); this._refreshCanUpgradeHints();
this._refreshSkillBindings(); this._refreshSkillBindings();
@ -4496,9 +4502,6 @@ export class CocosBagBoardView {
this._requestSessionRebuild(false); this._requestSessionRebuild(false);
this._scheduleComposeFxFlush(); this._scheduleComposeFxFlush();
} }
if (this._deploySync && this._map.gridsInitialized) {
this._deploySync.reconcileFromMerge('glyphRewritten');
}
break; break;
case MergeEventType.PlaceRejected: case MergeEventType.PlaceRejected:
if (event.reason === PlaceRejectReason.NotPrepPhase) { if (event.reason === PlaceRejectReason.NotPrepPhase) {

@ -2,8 +2,8 @@ import { color } from "cc";
import { Singleton } from "../../mx/tools/Singleton"; import { Singleton } from "../../mx/tools/Singleton";
import { LevelFieldResolver } from "../manager/LevelFieldResolver"; import { LevelFieldResolver } from "../manager/LevelFieldResolver";
import { SkillMultiplyType, TableNames } from "./ConfigTableData"; import { SkillMultiplyType, TableNames } from "./ConfigTableData";
import { heroNormalSkillId, isBasicHero } from '../battle/config/BattleHeroTable'; import { isBasicHero } from '../battle/config/BattleHeroTable';
import { resolveAtkLevelCoef } from '../battle/combat/TowerStatResolver'; import { deriveTowerSetupStats } from '../battle/combat/TowerStatResolver';
import type { IBattleRuntimeHandle } from '../battle/types/ProjectBattleTypes'; import type { IBattleRuntimeHandle } from '../battle/types/ProjectBattleTypes';
import MTools from "../../mx/tools/MTools"; import MTools from "../../mx/tools/MTools";
import { DailyWinStats } from '../manager/DailyWinStats'; import { DailyWinStats } from '../manager/DailyWinStats';
@ -881,22 +881,9 @@ export class ConfigProjectData extends Singleton {
// 旧词条 Skill.weapon 已删:DPS 乘区用传入 skills(局外带入/调试),无则按 1 // 旧词条 Skill.weapon 已删:DPS 乘区用传入 skills(局外带入/调试),无则按 1
const dpsMult = this.calculateDPSWeight(skills as ITableSkill[], weapon1Id); const dpsMult = this.calculateDPSWeight(skills as ITableSkill[], weapon1Id);
const setup = deriveTowerSetupStats(w1, composeLevel);
const levelLimit = w1.level_limit > 0 ? w1.level_limit : composeLevel; if (!(setup.attackSpeed > 0)) return 0;
const effectiveLevel = Math.max(1, Math.min(composeLevel, levelLimit)); return dpsMult * setup.attack * setup.attackSpeed;
const weaponRow = this._getHeroWeaponRow(w1);
const exclusiveMul = weaponRow ? gg.equip.getEquipExclusiveMul(w1.id, weaponRow) : 1;
const weaponAtk = (weaponRow?.atk ?? 0) * exclusiveMul;
const allAttack = w1.atk * resolveAtkLevelCoef(effectiveLevel) + weaponAtk;
const skillId = heroNormalSkillId(w1, effectiveLevel);
const skillRow = skillId > 0
? gg.data.table.getTableData<ITableSkill>(TableNames.Skill, skillId)
: null;
const baseCd = skillRow?.cd ?? 1;
if (baseCd <= 0) return 0;
return dpsMult * allAttack / baseCd;
} }
/** 计算一组词条对指定武器的理论 DPS 乘区(暴击期望 × 其他乘区) */ /** 计算一组词条对指定武器的理论 DPS 乘区(暴击期望 × 其他乘区) */

@ -250,8 +250,9 @@ export class BattleGameRewriteGlyphPresenter {
else node.destroy(); else node.destroy();
} }
/** 中断属性卡表现 */ /** 中断属性卡表现(须先提交未换皮回调,避免卡已耗尽却未改字) */
private _abortAttrFx(): void { private _abortAttrFx(): void {
this._flushAttrRewriteIfNeeded();
this._attrGen++; this._attrGen++;
const node = this._attrFxNode; const node = this._attrFxNode;
this._attrFxNode = null; this._attrFxNode = null;

@ -1303,6 +1303,10 @@ export class Monster extends Component {
onComplete?.(); onComplete?.();
return false; return false;
} }
// 行军用 PRIVATE_CACHE;死亡轨含附件切换,缓存模式无法起播,须切 REALTIME
if (typeof this.anim.setAnimationCacheMode === 'function') {
this.anim.setAnimationCacheMode(sp.SpineAnimationCacheMode.REALTIME);
}
// 禁止直接 findAnimation:Spine runtime 未就绪时会抛 Cannot read properties of null (reading 'lv') // 禁止直接 findAnimation:Spine runtime 未就绪时会抛 Cannot read properties of null (reading 'lv')
this._animBaseTimeScale = 1; this._animBaseTimeScale = 1;
const ok = BattleSpinePlayback.play(this.anim, anim, { const ok = BattleSpinePlayback.play(this.anim, anim, {

Loading…
Cancel
Save