434 lines
8.3 KiB
JavaScript
434 lines
8.3 KiB
JavaScript
/*******************************************************************************
|
|
*
|
|
* 剧情管理
|
|
*
|
|
*
|
|
*
|
|
* 2023.06.25
|
|
******************************************************************************/
|
|
|
|
const BridgeController = require( "bridge.controller" );
|
|
const PDF = require( "plot.define" );
|
|
|
|
const TDefine = require( "trace.define" );
|
|
const TTT = TDefine.TraceType;
|
|
|
|
const PlotManager = cc.Class( {
|
|
|
|
extends: BridgeController,
|
|
|
|
// 初始化配置数据
|
|
initConfig: function() {
|
|
|
|
this.units = {};
|
|
|
|
// 插件
|
|
nx.plugin.add( this, [ "view" ] );
|
|
|
|
// 视图创建
|
|
this.vbuild( PDF.ViewPlot );
|
|
|
|
// 全局支持
|
|
nx.bridge.plot = this;
|
|
|
|
},
|
|
|
|
// 注册监听事件
|
|
registerEvents: function() {
|
|
},
|
|
|
|
// 注册协议接受事件
|
|
registerProtocals: function() {
|
|
|
|
// 前端准备完毕
|
|
this.RegisterProtocal( 10371, this.onCommited.bind( this ) );
|
|
this.RegisterProtocal( 10372, this.onPlotData.bind( this ) );
|
|
|
|
},
|
|
|
|
// 从服务器初始化数据
|
|
reqBaseFromServer: function( _cb ) {
|
|
|
|
// 如果当前正在引导,则不重建
|
|
if( this.isDoing() ) {
|
|
nx.dt.fnInvoke( _cb, true );
|
|
return;
|
|
}
|
|
|
|
this.rebuild( ( _ret, _data ) => {
|
|
nx.dt.fnInvoke( _cb, _ret, _data );
|
|
// 掉线重新激活
|
|
if( nx.bridge.mainui ) {
|
|
nx.bridge.mainui.tryPlot();
|
|
}
|
|
} );
|
|
},
|
|
|
|
// 系统重建
|
|
rebuild: function( _cb ) {
|
|
|
|
// 清理
|
|
this.records = {};
|
|
this.configs = null;
|
|
this.vreset();
|
|
|
|
// 开关
|
|
let open = nx.storage.getNumber( PDF.KEY_PLOT_OPEN, 1, true );
|
|
this.opened = ( open == 1 );
|
|
|
|
// 重读配置
|
|
let path = cc.path.join( "configs/plots", "catalogs" );
|
|
nx.res.loadJson( path, ( _err, _data ) => {
|
|
|
|
if( _err ) {
|
|
nx.error( "$Plot:配置加载失败:", path );
|
|
nx.dt.fnInvoke( _cb, false );
|
|
return;
|
|
}
|
|
|
|
this.configs = _data;
|
|
this.records = nx.storage.getObject( PDF.KEY_PLOTS, true );
|
|
if( nx.dt.objEmpty( this.records ) ) {
|
|
this.records = {
|
|
ids: [],
|
|
};
|
|
}
|
|
this.reqBaseData( _cb );
|
|
} );
|
|
|
|
},
|
|
|
|
// 请求剧情信息
|
|
reqBaseData: function( _cb ) {
|
|
|
|
this.SendProtocal( 10372, {}, _cb );
|
|
},
|
|
|
|
// 剧情信息
|
|
onPlotData: function( _data ) {
|
|
|
|
if( !this.isGoodData( _data ) ) {
|
|
return;
|
|
}
|
|
|
|
let ids = [];
|
|
let group = _data.guide_group || [];
|
|
group.forEach( t => {
|
|
ids.push( t.id );
|
|
} );
|
|
this.records.ids = ids;
|
|
|
|
},
|
|
|
|
// 上传剧情完成
|
|
reqComplete: function( _id, _cb ) {
|
|
|
|
// 已经提交过了
|
|
if( this.preCommited ) {
|
|
nx.warn( `$Plot:已经提前完成过了!` );
|
|
nx.dt.fnInvoke( _cb, true );
|
|
return;
|
|
}
|
|
|
|
this.SendProtocal( 10371, {
|
|
id: _id + "",
|
|
}, _cb );
|
|
|
|
// 埋点
|
|
if( nx.mTrace ) {
|
|
nx.mTrace.trace( TTT.plotDone, _id );
|
|
}
|
|
|
|
},
|
|
|
|
// 剧情上传
|
|
onCommited: function( _data ) {
|
|
|
|
if( !this.isGoodData( _data ) ) {
|
|
return;
|
|
}
|
|
|
|
this.preCommited = true;
|
|
},
|
|
|
|
// 引导开关
|
|
openPlot: function( _open ) {
|
|
|
|
this.opened = !!_open;
|
|
nx.storage.set( PDF.KEY_PLOT_OPEN, _open ? 1 : 0, true );
|
|
},
|
|
|
|
// 剧情触发
|
|
fire: function( _id, _cb, _force = false ) {
|
|
|
|
// 进行中
|
|
let cur = this.vget( "id" );
|
|
if( nx.dt.strNEmpty( cur ) ) {
|
|
nx.error( "$Plot:进行中,播放失败:", cur, _id );
|
|
nx.dt.fnInvoke( _cb, false, "PlotFailed" );
|
|
return false;
|
|
}
|
|
|
|
// 获取配置
|
|
let info = this.queryCfgs( _id );
|
|
if( nx.dt.objEmpty( info ) ) {
|
|
nx.dt.fnInvoke( _cb, false, "PlotFailed" );
|
|
return false;
|
|
}
|
|
|
|
// 剧情不跳过
|
|
if( !this.opened && info.type != "dia" ) {
|
|
nx.warn( "$Plot:引导未开启" );
|
|
nx.dt.fnInvoke( _cb, false, "PlotFailed" );
|
|
return false;
|
|
}
|
|
|
|
// 条件判断
|
|
let ret = nx.bridge.checkConditions( info.conditions );
|
|
if( nx.dt.objNEmpty( ret ) && !_force ) {
|
|
// nx.warn( "$Plot:不滿足觸發條件:", _id );
|
|
nx.dt.fnInvoke( _cb, false, "PlotNoConds" );
|
|
return false;
|
|
}
|
|
|
|
// 是否触发过
|
|
if( nx.dt.arrMember( this.records.ids, _id ) ) {
|
|
nx.warn( "$Plot:劇情重複觸發:", _id );
|
|
nx.bridge.vset( "DailyPop", 1 );
|
|
nx.dt.fnInvoke( _cb, false, "PlotRepeat" );
|
|
return false;
|
|
}
|
|
|
|
// 预先标记引导中
|
|
this.vset( "id", _id, false );
|
|
|
|
// 载入剧本
|
|
let path = cc.path.join( "configs/plots/jsons", info.json );
|
|
nx.res.loadJson( path, ( _err, _data ) => {
|
|
|
|
if( _err ) {
|
|
this.vset( "id", "" );
|
|
nx.error( "$Plot:载入剧本失败:", path );
|
|
nx.dt.fnInvoke( _cb, false, "PlotFailed" );
|
|
return;
|
|
}
|
|
|
|
this.cbDone = _cb;
|
|
this.setCurrent( _id, _data );
|
|
} );
|
|
|
|
return true;
|
|
},
|
|
|
|
// 强制触发剧情
|
|
fireForce: function( _id, _cb ) {
|
|
|
|
// 从记录删除
|
|
nx.dt.arrDelete( this.records.ids, ( m ) => {
|
|
return m == _id;
|
|
} );
|
|
|
|
this.fire( _id, _cb, true );
|
|
},
|
|
|
|
// 设置当前剧情
|
|
setCurrent: function( _id, _json ) {
|
|
|
|
// 清理
|
|
let id = "" + _id;
|
|
if( nx.dt.strEmpty( id ) ) {
|
|
this.vreset();
|
|
return;
|
|
}
|
|
|
|
// 新设置
|
|
this.vset( "info", _json );
|
|
this.vset( "skip", _json.skip );
|
|
this.vset( "total", _json.steps.length );
|
|
this.vset( "step", -1 );
|
|
this.vset( "id", id );
|
|
this.preCommited = false;
|
|
|
|
nx.debug( "$Plot:开始剧情:", id );
|
|
|
|
// 埋点
|
|
if( nx.mTrace ) {
|
|
nx.mTrace.trace( TTT.plotStart, id );
|
|
}
|
|
},
|
|
|
|
// 下一步
|
|
next: function() {
|
|
|
|
// 剧情完成
|
|
let step = this.vget( "step" ) + 1;
|
|
if( step >= this.vget( "total" ) ) {
|
|
this.done();
|
|
return;
|
|
}
|
|
|
|
if( CC_DEBUG ) {
|
|
let info = this.vget( "info" );
|
|
let data = info ? info.steps[ step ] : null;
|
|
console.log( "next:", step, data );
|
|
}
|
|
|
|
// 设置
|
|
this.vset( "step", step );
|
|
|
|
// 埋点
|
|
if( nx.mTrace ) {
|
|
nx.mTrace.trace( TTT.plotStep, this.vget( "id" ), step );
|
|
}
|
|
},
|
|
|
|
// 引导中
|
|
isDoing: function() {
|
|
|
|
let id = this.vget( "id" );
|
|
return nx.dt.strNEmpty( id );
|
|
},
|
|
|
|
// 剧情完成
|
|
done: function() {
|
|
|
|
let id = this.vget( "id" );
|
|
nx.debug( "$Plot:引导完成.", id );
|
|
|
|
// 关闭
|
|
this.vreset();
|
|
|
|
nx.bridge.vset( "CloseSpecial", null );
|
|
|
|
// 存档
|
|
this.records.ids.push( id );
|
|
nx.storage.setObject( PDF.KEY_PLOTS, this.records, true );
|
|
|
|
// 尝试一次弹窗
|
|
let tryPops = function() {
|
|
if( nx.bridge.popups ) {
|
|
nx.bridge.popups.tryPopup();
|
|
}
|
|
};
|
|
|
|
// 是否有串联剧情
|
|
let self = this;
|
|
let next = function() {
|
|
|
|
let info = self.queryCfgs( id );
|
|
if( !info || nx.dt.strEmpty( info.next ) ) {
|
|
tryPops();
|
|
return;
|
|
}
|
|
|
|
self.fire( info.next, ( _ret ) => {
|
|
if( !_ret ) {
|
|
tryPops();
|
|
}
|
|
} );
|
|
};
|
|
|
|
// 上传
|
|
this.reqComplete( id, () => {
|
|
nx.dt.fnInvoke( this.cbDone, true );
|
|
this.cbDone = null;
|
|
next();
|
|
} );
|
|
|
|
},
|
|
|
|
// 获取当前步骤剧本
|
|
stepData: function() {
|
|
|
|
let info = this.vget( "info" );
|
|
let step = this.vget( "step" );
|
|
if( step == -1 ) {
|
|
return null;
|
|
}
|
|
|
|
let data = info ? info.steps[ step ] : null;
|
|
if( nx.dt.objEmpty( data ) ) {
|
|
nx.error( "$Plot:获取当前剧本失败:", this.vget( "id" ), step );
|
|
}
|
|
return data;
|
|
},
|
|
|
|
// 是否已经解锁
|
|
isUnlocked: function( _id ) {
|
|
return nx.dt.arrMember( this.records.ids, _id );
|
|
},
|
|
|
|
// ============================================================
|
|
// 引导元素
|
|
// ============================================================
|
|
|
|
// 注册引导元素
|
|
regUnit: function( _key, _node, _cb ) {
|
|
|
|
let unit = this.units[ _key ];
|
|
if( unit ) {
|
|
nx.error( "$Plot:重复注册元素:", _key );
|
|
return;
|
|
}
|
|
|
|
this.units[ _key ] = {
|
|
node: _node, // 聚焦节点
|
|
cb: _cb, // 触发回调
|
|
};
|
|
nx.debug( "$Plot:注册元素:", _key );
|
|
|
|
},
|
|
|
|
// 注销引导元素
|
|
unregUnit: function( _key ) {
|
|
|
|
let unit = this.units[ _key ];
|
|
if( unit ) {
|
|
nx.debug( "$Plot:注销元素:", _key );
|
|
delete this.units[ _key ];
|
|
}
|
|
},
|
|
|
|
// 查询引导元素
|
|
queryUnit: function( _key ) {
|
|
|
|
let unit = this.units[ _key ];
|
|
if( !unit ) {
|
|
nx.error( "$Plot:查询元素失败:", _key );
|
|
return null;
|
|
}
|
|
|
|
return this.units[ _key ];
|
|
},
|
|
|
|
// 查询引导配置
|
|
queryCfgs: function( _id ) {
|
|
|
|
let key = nx.frame.vget( "hMode" ) ? `H${ _id }` : _id;
|
|
let info = this.configs[ key ];
|
|
if( nx.dt.objEmpty( info ) ) {
|
|
info = this.configs[ _id ];
|
|
}
|
|
|
|
if( nx.dt.objEmpty( info ) ) {
|
|
nx.error( "$Plot:配置缺失:", _id );
|
|
return null;
|
|
}
|
|
|
|
return info;
|
|
},
|
|
|
|
// ============================================================
|
|
// 剧情事件
|
|
// ============================================================
|
|
|
|
// 发送
|
|
postKey: function( _key ) {
|
|
nx.debug( "$Plot:事件 ", _key );
|
|
this.vset( "key", _key );
|
|
},
|
|
|
|
} );
|
|
|
|
// 模块导出
|
|
module.exports = PlotManager; |