|
|
|
|
import { _decorator, Component, Label, Node, Tween, tween } from 'cc';
|
|
|
|
|
import { GBundle } from '../game/ConfigRes';
|
|
|
|
|
import { TetriType } from '../game/ConfigProjectData';
|
|
|
|
|
import { tetriNode } from './tetriNode';
|
|
|
|
|
const { ccclass } = _decorator;
|
|
|
|
|
|
|
|
|
|
/**方块功能脚本不是战斗类型的方块
|
|
|
|
|
* TetriType == 3 每秒给一个金币
|
|
|
|
|
* TetriType == 4 每秒恢复特定的玩家血量
|
|
|
|
|
*/
|
|
|
|
|
@ccclass('tetriAbility')
|
|
|
|
|
export class tetriAbility extends Component {
|
|
|
|
|
|
|
|
|
|
/** 旧版:飘字挂在「角色」local(0,50)→(0,150),角色带 mainPosi 与 scale */
|
|
|
|
|
private static readonly ICON_PREFAB_SCALE = 4;
|
|
|
|
|
private static readonly ICON_FLOAT_START_Y = 50;
|
|
|
|
|
private static readonly ICON_FLOAT_END_Y = 150;
|
|
|
|
|
private static readonly ICON_LAYOUT: Record<string, { scaleX: number; scaleY: number; mainPosi: { x: number; y: number } }> = {
|
|
|
|
|
Tetris_coin_1: { scaleX: -0.25, scaleY: 0.25, mainPosi: { x: -2.225, y: -19.558 } },
|
|
|
|
|
Tetris_heal_1: { scaleX: -0.15, scaleY: 0.15, mainPosi: { x: -1.523, y: -8.577 } },
|
|
|
|
|
Tetris_heal_2: { scaleX: -0.15, scaleY: 0.15, mainPosi: { x: -0.473, y: -10.624 } },
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private _config: ITableBattleCube | null = null;
|
|
|
|
|
private _curentWeaponId: number = 0;
|
|
|
|
|
|
|
|
|
|
cdTimeFix = 0
|
|
|
|
|
cdTime = 0
|
|
|
|
|
|
|
|
|
|
addValue = 0
|
|
|
|
|
|
|
|
|
|
setConfig(config: ITableBattleCube) {
|
|
|
|
|
this._config = config
|
|
|
|
|
this._curentWeaponId = config.weaponid
|
|
|
|
|
this._removeLegacyRoleNodes()
|
|
|
|
|
this.setView()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start() {
|
|
|
|
|
this._removeLegacyRoleNodes()
|
|
|
|
|
if (this._config) {
|
|
|
|
|
this.setView()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 旧版会在方块下挂「角色」预制体;现改为方块 spine 表情,不再创建 */
|
|
|
|
|
private _removeLegacyRoleNodes(): void {
|
|
|
|
|
if (!this.node?.isValid) return;
|
|
|
|
|
const kids = this.node.children.slice();
|
|
|
|
|
for (const ch of kids) {
|
|
|
|
|
if (ch?.isValid && ch.name === '角色') {
|
|
|
|
|
ch.destroy();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setView() {
|
|
|
|
|
let conf = gg.data.project.getWeaponData(this._curentWeaponId)
|
|
|
|
|
if (!conf) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
this.cdTime = conf.cd
|
|
|
|
|
this.cdTimeFix = conf.cd
|
|
|
|
|
let weaponLevel = gg.data.project.getWeaponLevel(conf.id);
|
|
|
|
|
let levelPara = gg.data.project.getLevelParaByWeaponLevel(weaponLevel, conf.id)
|
|
|
|
|
let weapon_para = conf.weapon_para
|
|
|
|
|
|
|
|
|
|
this.addValue = Math.floor(weapon_para * levelPara)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 挂到方块根节点时,用锚点复刻旧版「角色」→飘字层级(prefab scale=4 由角色 scale 缩小) */
|
|
|
|
|
private _setupFloatingIcon(iconNode: Node, addNum: number): void {
|
|
|
|
|
const layout = tetriAbility.ICON_LAYOUT[this._config?.cubename ?? '']
|
|
|
|
|
?? { scaleX: -0.25, scaleY: 0.25, mainPosi: { x: 0, y: 0 } };
|
|
|
|
|
|
|
|
|
|
Tween.stopAllByTarget(iconNode);
|
|
|
|
|
|
|
|
|
|
const anchor = new Node('__floatIconAnchor');
|
|
|
|
|
anchor.setParent(this.node);
|
|
|
|
|
anchor.setPosition(layout.mainPosi.x, layout.mainPosi.y, 0);
|
|
|
|
|
anchor.setScale(layout.scaleX, layout.scaleY, 1);
|
|
|
|
|
|
|
|
|
|
iconNode.setParent(anchor);
|
|
|
|
|
iconNode.active = true;
|
|
|
|
|
iconNode.setScale(tetriAbility.ICON_PREFAB_SCALE, tetriAbility.ICON_PREFAB_SCALE, 1);
|
|
|
|
|
iconNode.setPosition(0, tetriAbility.ICON_FLOAT_START_Y, 0);
|
|
|
|
|
iconNode.opacity = 100;
|
|
|
|
|
|
|
|
|
|
const labNode = iconNode.getChildByName('lab');
|
|
|
|
|
// prefab 默认 scaleX=-1,配合 anchor 负 scaleX,文字方向与旧版一致
|
|
|
|
|
labNode?.setScale(-1, 1, 1);
|
|
|
|
|
|
|
|
|
|
const lab = labNode?.getComponent(Label);
|
|
|
|
|
if (lab) {
|
|
|
|
|
lab.string = '+' + addNum.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tween(iconNode)
|
|
|
|
|
.to(0.5, { y: tetriAbility.ICON_FLOAT_END_Y, opacity: 255 })
|
|
|
|
|
.call(() => {
|
|
|
|
|
Tween.stopAllByTarget(iconNode);
|
|
|
|
|
if (iconNode?.isValid) {
|
|
|
|
|
labNode?.setScale(-1, 1, 1);
|
|
|
|
|
iconNode.setScale(tetriAbility.ICON_PREFAB_SCALE, tetriAbility.ICON_PREFAB_SCALE, 1);
|
|
|
|
|
gg.res.putNode(iconNode);
|
|
|
|
|
}
|
|
|
|
|
if (anchor?.isValid) {
|
|
|
|
|
anchor.destroy();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update(deltaTime: number) {
|
|
|
|
|
if (!this._config) return;
|
|
|
|
|
if (!this.node.getComponent(tetriNode)?.isSettled) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!gg.game?.CurentBattle?.canUpdateFrame() && !gg.game?.CurentBattle?.IsWarnTimeActive) return;
|
|
|
|
|
this.cdTime += deltaTime * gg.game.CurentBattle.TimeScale
|
|
|
|
|
if (this.cdTime >= this.cdTimeFix) {
|
|
|
|
|
this.cdTime = 0
|
|
|
|
|
this.addValueFunc()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addValueFunc() {
|
|
|
|
|
if (!this._config) return;
|
|
|
|
|
if (!this.node.getComponent(tetriNode)?.isSettled) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let getNodeLevel = this.node.getComponent(tetriNode)?.getNodeLevel() || 1
|
|
|
|
|
let addNum = this.addValue * getNodeLevel;
|
|
|
|
|
|
|
|
|
|
if (this._config.type == TetriType.Tetris_BaseGold) {
|
|
|
|
|
gg.game.CurentBattle.curentCoinNumChange(addNum);
|
|
|
|
|
void gg.res.getNodeAsync('角色/', '金币icon', GBundle.tetriCards).then((iconNode) => {
|
|
|
|
|
if (!iconNode?.isValid || !this.node?.isValid) return;
|
|
|
|
|
this._setupFloatingIcon(iconNode, addNum);
|
|
|
|
|
});
|
|
|
|
|
} else if (this._config.type == TetriType.Tetris_Baseheal) {
|
|
|
|
|
gg.game.CurentBattle.addWallHp(addNum);
|
|
|
|
|
void gg.res.getNodeAsync('角色/', '爱心icon', GBundle.tetriCards).then((iconNode) => {
|
|
|
|
|
if (!iconNode?.isValid || !this.node?.isValid) return;
|
|
|
|
|
this._setupFloatingIcon(iconNode, addNum);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|