Files
2026-05-23 22:10:14 +08:00

364 lines
11 KiB
JavaScript

/******************************************************************
*
* 开盲盒
*
******************************************************************/
const ActPage = require( "act.page.base" );
const NxSpine = require( "nx.fx.spine" );
const ItemLayout = require( "cmp.item.layout" );
const TipsController = require( "tips_controller" );
const BridgeItemBinder = require( "bridge.binder.item.icon.count" );
const BKC = require( "backpack_controller" );
cc.Class( {
extends: ActPage,
properties: {
nodBG: { default: null, type: cc.Node },
spRole: { default: null, type: NxSpine },
spMini: { default: null, type: NxSpine },
spBox: { default: null, type: NxSpine },
nodGifts: { default: null, type: cc.Node },
nodAd: { default: null, type: cc.Node },
nodGround: { default: null, type: cc.Node },
nodDate: { default: null, type: cc.Node },
nodOps: { default: null, type: cc.Node },
nodCombine: { default: null, type: cc.Node },
nodBars: { default: null, type: cc.Node },
nodCoin: { default: null, type: BridgeItemBinder },
nodFrags: { default: null, type: BridgeItemBinder },
nodRewards: { default: null, type: ItemLayout },
},
// 初始化
build: function( _data ) {
this._super( _data );
// 依赖缺失
if( !this.mod || nx.dt.objEmpty( this.data ) ) {
return;
}
// 基本信息
this.configs = this.mod.queryConfigs( this.data.camp_id );
this.freshBasic();
},
// 显示
onEnable: function() {
// 操作锁定
nx.gui.setActive( this.nodOps, "on", true );
nx.gui.setActive( this.nodOps, "off", false );
// 盲盒动画
this.spBox.action( "action", true );
this.mod.freshTips();
// 刷新活动日期
this.freshDate();
},
// 关闭
onDisable: function() {
if( this.voiceHandle ) {
nx.audio.stopSFX( this.voiceHandle );
this.voiceHandle = null;
}
},
// ------------------------------------------------------------
// 基础相关
// ------------------------------------------------------------
// 基本信息
freshBasic: function() {
// 置空
if( !this.configs ) {
nx.gui.setActive( this, "right", false );
return;
}
nx.gui.setActive( this, "right", true );
// 背景
let path = cc.path.join( "prefab/acts/blindBox/themes", this.configs.theme, "bg" );
nx.gui.setSpriteFrame( this.nodBG, "", path );
// 展台
path = cc.path.join( "prefab/acts/blindBox/themes", this.configs.theme, "ground" );
nx.gui.setSpriteFrame( this.nodGround, "", path );
// Mini台
path = cc.path.join( "prefab/acts/blindBox/themes", this.configs.theme, "tai" );
nx.gui.setSpriteFrame( this.spMini, "tai", path );
// 广告图
let key = `${ this.configs.partner_id }_${ this.configs.skin_id }`;
path = cc.path.join( "locals/{lang}/images/blindbox", key, "ad" );
nx.gui.setSpriteFrame( this.nodAd, "", nx.res.fmtPath( path ) );
// 皮肤展示
this.partnerRes = "";
let SKIN = game.configs.partner_skin_data.data_skin_info[ this.configs.skin_id ];
if( SKIN ) {
let bsp = PathTool.getSpinePath( SKIN.res_id, "show", false );
this.spRole.play( bsp, this.configs.drama, null, true );
let msp = PathTool.getSpinePath( SKIN.res_id, SKIN.res_id, false );
this.spMini.play( msp, "stand2", null, true );
this.partnerRes = SKIN.res_id;
}
// 奖励面板
path = cc.path.join( "locals/{lang}/images/blindbox", key, "panel" );
nx.gui.setSpriteFrame( this.nodGifts, "", nx.res.fmtPath( path ) );
// 大奖展示
let snode = nx.gui.find( this.nodGifts, "sp" );
if( snode ) {
let rewards = this.configs.big_reward;
for( let i = 0; i < snode.children.length; ++i ) {
let cmp = nx.gui.getComponent( snode.children[ i ], "", "cmp.item.base" );
if( cmp ) cmp.setData( rewards[ i ][ 0 ], rewards[ i ][ 1 ] );
}
}
// 小奖展示
let mnode = nx.gui.find( this.nodGifts, "items" );
if( mnode ) {
let rewards = this.configs.good_gift;
for( let i = 0; i < mnode.children.length; ++i ) {
let cmp = nx.gui.getComponent( mnode.children[ i ], "", "cmp.item.base" );
if( cmp ) {
cmp.setData( rewards[ i ][ 0 ], rewards[ i ][ 1 ] );
if( rewards[ i ][ 1 ] == "?" ) {
nx.gui.setString( cmp, "count", "?" );
}
}
}
}
// 必出奖励
this.nodRewards.rebuild( this.configs.must_reward );
// 跳过动画
this.setSkipAnim( false );
// 盲盒动画
path = cc.path.join( "locals/{lang}/images/blindbox", key, "box/action" );
this.spBox.play( path, "action", null, true );
// 道具绑定
this.nodCoin.setID( this.configs.item_id );
// 碎片绑定
let frags = this.configs.skin_debris_id;
nx.gui.setString( this.nodFrags, "total", frags[1] );
this.nodFrags.setID( frags[0], () => {
this.freshCombine();
} );
// 红点绑定
let tip1 = nx.gui.getComponent( this.nodOps, "on/once/tip", "nx.vb.visible" );
if( tip1 ) {
tip1.setTarget( nx.mTip, this.mod.getTipKey( "once" ) );
}
let tip2 = nx.gui.getComponent( this.nodOps, "on/ten/tip", "nx.vb.visible" );
if( tip2 ) {
tip2.setTarget( nx.mTip, this.mod.getTipKey( "ten" ) );
}
// 操作刷新
this.freshOps();
},
// 刷新活动日期
freshDate: function() {
let time = nx.bridge.time.toNeedTime( this.data.end_time );
nx.gui.setString( this.nodDate, "txt", time );
},
// ------------------------------------------------------------
// 抽奖相关
// ------------------------------------------------------------
// 操作刷新
freshOps: function() {
// 按钮设置
let autoOp = function( _node, _draw ) {
let tinfo = gitemdata( _draw[ 0 ] );
if( !tinfo ) {
nx.error( `$BlindBox:道具无效! ${ _draw[ 0 ] }` );
return;
}
nx.bridge.setIcon( _node, "btn/list/icon", tinfo.icon );
nx.gui.setString( _node, "btn/list/num", _draw[ 1 ] );
}
// 操作刷新
autoOp( nx.gui.find( this.nodOps, "on/once" ), this.configs.loss_item_once[ 0 ] );
autoOp( nx.gui.find( this.nodOps, "off/once" ), this.configs.loss_item_once[ 0 ] );
autoOp( nx.gui.find( this.nodOps, "on/ten" ), this.configs.loss_item_ten[ 0 ] );
autoOp( nx.gui.find( this.nodOps, "off/ten" ), this.configs.loss_item_ten[ 0 ] );
},
// 抽奖
doRaffle: function( _once ) {
// 操作锁定
nx.gui.setActive( this.nodOps, "on", false );
nx.gui.setActive( this.nodOps, "off", true );
// 抽取
let self = this;
let raffle = function() {
self.mod.reqRaffle( _once, ( _ret, _data, _code ) => {
nx.gui.setActive( self.nodOps, "on", true );
nx.gui.setActive( self.nodOps, "off", false );
// 道具不足
if( !_ret && _code == 101 ) {
self.onTouchCoin();
}
} );
};
// 跳过动画
if( this.skipAnim ) {
return raffle();
}
// 动画播放
let anim = function( _key ) {
self.spBox.action( _key || "action2", false, ( _event ) => {
if( _event == "reward" ) {
raffle();
return;
}
if( _event == "complete" ) {
self.spBox.action( "action", null, true );
return;
}
} );
// 開啟音效
let path = cc.path.join( "prefab/acts/blindBox/audios", "open" );
nx.audio.playSFX( path, false );
};
// 执行长流程
this.mod.reqPreRaffle( _once, ( _ret, _data, _code ) => {
// 失败
if( !_ret ) {
nx.gui.setActive( self.nodOps, "on", true );
nx.gui.setActive( self.nodOps, "off", false );
// 道具不足
if( _code == 101 ) {
this.onTouchCoin();
}
return;
}
// 盲盒动画
anim( (_data.is_notice == 0 ) ? "action2" : "action3" );
} );
},
// 点击招募
onTouchOnce: function() {
this.doRaffle( true );
},
// 点击招募
onTouchTen: function() {
this.doRaffle( false );
},
// ------------------------------------------------------------
// 合成相关
// ------------------------------------------------------------
// 合成刷新
freshCombine: function() {
},
// 点击合成
onTouchCombine: function() {
let frags = this.configs.skin_debris_id;
BKC.getInstance().reqSkinCombine( frags[0], ( _ret, _data ) => {
} );
},
// ------------------------------------------------------------
// 动画相关
// ------------------------------------------------------------
// 动画切换
setSkipAnim: function( _skip ) {
this.skipAnim = !!_skip;
nx.gui.setActive( this.nodBars, "skip/ck/on", this.skipAnim );
nx.gui.setActive( this.nodBars, "skip/ck/off", !this.skipAnim );
},
// 动画切换
onTouchSkip: function() {
this.setSkipAnim( !this.skipAnim );
},
// 点击动画
onTouchSpine: function() {
if( nx.dt.strEmpty( this.partnerRes ) ) {
return;
}
if( this.voiceHandle ) {
nx.audio.stopSFX( this.voiceHandle );
this.voiceHandle = null;
}
let path = cc.path.join( "resDB/models", this.partnerRes, this.configs.voice );
nx.audio.playVoice( path, ( _err, _id ) => {
if( !_err ) {
this.voiceHandle = _id;
}
});
},
// ------------------------------------------------------------
// 其他
// ------------------------------------------------------------
// 点击道具
onTouchCoin: function() {
if( this.actRoot && this.configs ) {
this.actRoot.jumpToMenu( this.configs.shop_source_id );
}
},
// 点击规则
onTouchRule: function() {
let rule = this.mod ? this.mod.queryRule() : "";
if( nx.dt.strNEmpty( rule ) ) {
const TC = TipsController.getInstance();
TC.showTextPanel( "tip", rule );
}
},
} );