军团活动:粮草先行部分计算逻辑
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { Application, ChannelService, BackendSession } from "pinus";
|
||||
import { GUILD_ACTIVITY_TYPE, STATUS } from "../../../consts";
|
||||
import { GUILD_ACTIVITY_TYPE, STATUS, GUILD_ACTIVITY_STATUS } from "../../../consts";
|
||||
import { resResult } from "../../../pubUtils/util";
|
||||
import { getGuildActivityStatus } from "../../../services/guildActivityService";
|
||||
import { getGuildActivityStatus, getRaceActivityObj, getRaceActivityRank, getWoodenHorseList, calWoodenHorseAndSend } from "../../../services/guildActivityService";
|
||||
import { UserGuildModel } from "../../../db/UserGuild";
|
||||
|
||||
export default function (app: Application) {
|
||||
return new RaceActivityHandler(app);
|
||||
@@ -14,11 +15,39 @@ export class RaceActivityHandler {
|
||||
this.channelService = app.get('channelService');
|
||||
}
|
||||
|
||||
private aid = GUILD_ACTIVITY_TYPE.GATE_ACTIVITY; // 蛮夷入侵id
|
||||
private aid = GUILD_ACTIVITY_TYPE.RACE_ACTIVITY; // 蛮夷入侵id
|
||||
|
||||
// 进入粮草先行界面
|
||||
async getRaceActivity(msg: {}, session: BackendSession) {
|
||||
|
||||
const roleId = session.get('roleId');
|
||||
const serverId = session.get('serverId');
|
||||
const guildCode = session.get('guildCode');
|
||||
if(!guildCode) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
|
||||
|
||||
let statusResult = getGuildActivityStatus(this.aid);
|
||||
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
let obj = getRaceActivityObj();
|
||||
let woodenHorse = await obj.getWoodenHorse(guildCode, serverId);
|
||||
if(!woodenHorse) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
|
||||
|
||||
let events = obj.getEvents(guildCode, woodenHorse.distance);
|
||||
let ranks = await getRaceActivityRank(guildCode, serverId);
|
||||
let hasJoin = obj.hasJoin(guildCode, roleId);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
...statusResult,
|
||||
hasJoin,
|
||||
woodenHorse,
|
||||
...ranks,
|
||||
events
|
||||
});
|
||||
}
|
||||
|
||||
// 加入木马
|
||||
async join(msg: {}, session: BackendSession) {
|
||||
|
||||
const roleId = session.get('roleId');
|
||||
const roleName = session.get('roleName');
|
||||
const serverId = session.get('serverId');
|
||||
@@ -28,15 +57,57 @@ export class RaceActivityHandler {
|
||||
let statusResult = getGuildActivityStatus(this.aid);
|
||||
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
|
||||
|
||||
let obj = getRaceActivityObj();
|
||||
|
||||
let myGuild = await UserGuildModel.getMyGuild(roleId, 'job');
|
||||
let woodenHorse = obj.joinWoodenHorse(guildCode, roleId, roleName, myGuild.job);
|
||||
if(!woodenHorse) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
|
||||
|
||||
let events = obj.getEvents(guildCode, woodenHorse.distance);
|
||||
let hasJoin = obj.hasJoin(guildCode, roleId);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
...statusResult,
|
||||
hasJoin: true,
|
||||
woodenHorse: {},
|
||||
guildRank:[]
|
||||
hasJoin,
|
||||
woodenHorse,
|
||||
events
|
||||
});
|
||||
}
|
||||
|
||||
// 打开竞赛页面
|
||||
async getRace(msg: {}, session: BackendSession) {
|
||||
|
||||
const roleId = session.get('roleId');
|
||||
const roleName = session.get('roleName');
|
||||
const serverId = session.get('serverId');
|
||||
const guildCode = session.get('guildCode');
|
||||
if(!guildCode) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
|
||||
|
||||
let statusResult = getGuildActivityStatus(this.aid);
|
||||
if(!statusResult) return resResult(STATUS.DIC_DATA_NOT_FOUND);
|
||||
if(statusResult.status != GUILD_ACTIVITY_STATUS.START) {
|
||||
return resResult(STATUS.GUILD_ACTIVITY_NOT_OPEN);
|
||||
}
|
||||
|
||||
let obj = getRaceActivityObj();
|
||||
let woodenHorse = await obj.getWoodenHorse(guildCode, serverId);
|
||||
if(!woodenHorse) return resResult(STATUS.GUILD_AUTH_NOT_ENOUGH);
|
||||
|
||||
let events = obj.getEvents(guildCode, woodenHorse.distance);
|
||||
let hasJoin = obj.hasJoin(guildCode, roleId);
|
||||
|
||||
let woodenHorseList = await getWoodenHorseList(guildCode, serverId);
|
||||
|
||||
return resResult(STATUS.SUCCESS, {
|
||||
...statusResult,
|
||||
hasJoin,
|
||||
woodenHorseList,
|
||||
events
|
||||
});
|
||||
}
|
||||
|
||||
async test(msg: { serverId: number }, session: BackendSession) {
|
||||
let {serverId} = msg;
|
||||
await calWoodenHorseAndSend(serverId);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Application, ChannelService } from 'pinus';
|
||||
import { sendAllGuildRanks, sendGuildActEndMsg } from '../../../services/guildActivityService';
|
||||
import { sendAllGuildRanks, sendGuildActEndMsg, calWoodenHorseAndSend } from '../../../services/guildActivityService';
|
||||
|
||||
export default function (app: Application) {
|
||||
return new GuildActivityRemote(app);
|
||||
@@ -27,4 +27,11 @@ export class GuildActivityRemote {
|
||||
public async guildActivityEnd(aid: number) {
|
||||
await sendGuildActEndMsg(aid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算粮草先行木马状态并发送
|
||||
*/
|
||||
public async calWoodenHorseAndSend(serverId: number) {
|
||||
await calWoodenHorseAndSend(serverId);
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@ import { gameData, getGuildAuctionRewards, getCityActivityRewards } from "../pub
|
||||
import { getCurHourPoint, getCutDay, nowSeconds } from "../pubUtils/timeUtil";
|
||||
import { GUILD_ACTIVITY_STATUS, GET_POINT_WAYS, GUILD_ACTIVITY_TYPE, REDIS_KEY, AUCTION_SOURCE, MAIL_TYPE, CITY_STATUS } from "../consts";
|
||||
import { Record, UserGuildActivityRecModel } from "../db/UserGuildActivityRec";
|
||||
import { GateMembersRec, GateActivityObject, CityActivityObject, CityParam, Member } from "../domain/battleField/guildActivity";
|
||||
import { GateMembersRec, GateActivityObject, CityActivityObject, CityParam, Member, RaceActivityObject, WoodenHorse } from "../domain/battleField/guildActivity";
|
||||
import { DicGuildActivity } from "../pubUtils/dictionary/DicGuildActivity";
|
||||
import { getUnionRank, getRank, getGuildKeyName, getMyUnionRank, getRankScore, getCityKeyName, getAllServers } from "./redisService";
|
||||
import { getUnionRank, getRank, getGuildKeyName, getMyUnionRank, getRankScore, getCityKeyName, getAllServers, getUnionRankRange } from "./redisService";
|
||||
import { GuildModel } from "../db/Guild";
|
||||
import { SimpleGuildRankParam, SimpleRoleRankParam } from "../domain/rank";
|
||||
import { SimpleGuildRankParam, SimpleRoleRankParam, SimpleGuildRankWithTimeParam } from "../domain/rank";
|
||||
import { getGuildChannelSid, getWorldChannelSid, getCityChannelSid } from "./chatChannelService";
|
||||
import { pinus } from "pinus";
|
||||
import { GuildActivityRecordModel } from "../db/GuildActivityRec";
|
||||
@@ -21,6 +21,7 @@ import { GuildActivityCityType, GuildActivityCityModel } from "../db/GuildActivi
|
||||
|
||||
let gateActivityObj: GateActivityObject;
|
||||
let cityActivityObj: CityActivityObject;
|
||||
let raceActivityObj: RaceActivityObject;
|
||||
export function getGateActivityObj() {
|
||||
if(!gateActivityObj) {
|
||||
gateActivityObj = new GateActivityObject();
|
||||
@@ -32,7 +33,14 @@ export function getCityActivityObj() {
|
||||
if(!cityActivityObj) {
|
||||
cityActivityObj = new CityActivityObject();
|
||||
}
|
||||
return cityActivityObj
|
||||
return cityActivityObj;
|
||||
}
|
||||
|
||||
export function getRaceActivityObj() {
|
||||
if(!raceActivityObj) {
|
||||
raceActivityObj = new RaceActivityObject();
|
||||
}
|
||||
return raceActivityObj;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,6 +167,53 @@ export async function getCityActivityRank(guildCode: string, serverId: number, c
|
||||
return rec;
|
||||
}
|
||||
|
||||
export async function getRaceActivityRank(guildCode: string, serverId: number) {
|
||||
let guildKey = REDIS_KEY.RACE_ACTIVITY;
|
||||
|
||||
let obj = getRaceActivityObj();
|
||||
let guildRankResult = await getUnionRank(guildKey, serverId, guildCode);
|
||||
let guildRank = new Array<SimpleGuildRankWithTimeParam>();
|
||||
for(let { rank, code, name, num } of guildRankResult.ranks) {
|
||||
let _obj = await obj.getWoodenHorse(code, serverId);
|
||||
let param = new SimpleGuildRankWithTimeParam(rank, code, name, num, _obj?_obj.time:0, _obj?_obj.durability:0);
|
||||
guildRank.push(param);
|
||||
}
|
||||
let myGuildRank: SimpleGuildRankWithTimeParam;
|
||||
if(guildRankResult.myRank) {
|
||||
let { rank, code, name, num } = guildRankResult.myRank;
|
||||
let _obj = await obj.getWoodenHorse(code, serverId);
|
||||
myGuildRank = new SimpleGuildRankWithTimeParam(rank, code, name, num, _obj?_obj.time:0, _obj?_obj.durability:0);
|
||||
} else {
|
||||
let guild = await GuildModel.findByCode(guildCode, serverId, 'name');
|
||||
let _obj = await obj.getWoodenHorse(guildCode, serverId);
|
||||
myGuildRank = new SimpleGuildRankWithTimeParam(0, guildCode, guild?.name, 0, _obj?_obj.time:0, _obj?_obj.durability:0);
|
||||
}
|
||||
return { guildRank, myGuildRank }
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取和自己同屏的5个木牛流马
|
||||
* @param guildCode
|
||||
* @param serverId
|
||||
*/
|
||||
export async function getWoodenHorseList(guildCode: string, serverId: number) {
|
||||
let guildKey = REDIS_KEY.RACE_ACTIVITY;
|
||||
let obj = getRaceActivityObj();
|
||||
let myRank = await getMyUnionRank(guildKey, serverId, guildCode);
|
||||
let startRank = myRank - 2 > 0? myRank - 2: 1;
|
||||
let endRank = startRank + 4;
|
||||
let range = await getUnionRankRange(guildKey, serverId, startRank, endRank);
|
||||
let woodenHorseList = new Array<WoodenHorse>();
|
||||
for(let { code } of range) {
|
||||
let woodenHorse = await obj.getWoodenHorse(code, serverId);
|
||||
if(woodenHorse) {
|
||||
woodenHorseList.push(woodenHorse);
|
||||
}
|
||||
}
|
||||
return woodenHorseList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获得军团活动排行榜
|
||||
* @param guildCode
|
||||
@@ -477,4 +532,45 @@ export function getCityStatus(guildCode: string, cityId: number, preCity: number
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
export async function calWoodenHorseAndSend(serverId: number) {
|
||||
console.log('calWoodenHorseAndSend');
|
||||
let guildKey = REDIS_KEY.RACE_ACTIVITY;
|
||||
let obj = getRaceActivityObj();
|
||||
let { ranks } = await getUnionRank(guildKey, serverId, '');
|
||||
let map = new Map<number, WoodenHorse[]>();
|
||||
let user = new Map<number, string>();
|
||||
|
||||
for(let i = 0; i < ranks.length; i++) {
|
||||
let { code } = ranks[i];
|
||||
for(let j = i; j <= i + 2; j++) {
|
||||
if(j <= ranks.length - 1 && !map.has(j)) {
|
||||
map.set(j, new Array<WoodenHorse>());
|
||||
}
|
||||
}
|
||||
user.set(i, code);
|
||||
for(let [rank, woodenHorseList] of map) {
|
||||
let woodenHorse = await obj.getWoodenHorse(code, serverId);
|
||||
if(woodenHorse) {
|
||||
map.get(rank).push(woodenHorse);
|
||||
} else {
|
||||
map.get(rank).push(new WoodenHorse(rank.toString(), 's',0));
|
||||
}
|
||||
let len = map.get(rank).length;
|
||||
let limit = 5;
|
||||
if(rank - 2 < 0) limit += rank - 2;
|
||||
if(rank + 2 > ranks.length - 1) limit -= (rank + 2) - (ranks.length - 1);
|
||||
|
||||
if( len >= limit) {
|
||||
// 发送
|
||||
let roleId = user.get(rank);
|
||||
console.log('send', roleId, woodenHorseList.length, JSON.stringify(woodenHorseList));
|
||||
|
||||
map.delete(rank);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ;
|
||||
}
|
||||
@@ -579,14 +579,13 @@ async function updateRankAtom(key: string, serverId: number, field: string, scor
|
||||
return newScore;
|
||||
}
|
||||
|
||||
async function generateUnionRank(key: string, serverId: number) {
|
||||
async function generateUnionRank(key: string, serverId: number, timelen = 10) {
|
||||
let unionKey = getKeyName(key, serverId, 'union'); // 联合的key
|
||||
let existsKey = await redisClient().existsAsync(unionKey);
|
||||
if(!existsKey) {
|
||||
let originKey = getKeyName(key, serverId);
|
||||
let timeKey = getKeyName(key, serverId, 'time');
|
||||
|
||||
let timelen = 10;
|
||||
let pow = Math.pow(10, timelen + 1);
|
||||
await redisClient().zunionstoreAsync(unionKey, 2, originKey, timeKey, 'WEIGHTS', pow, 1);
|
||||
await redisClient().expireAsync(unionKey, 10); // 10秒更新一次
|
||||
@@ -600,7 +599,7 @@ async function generateUnionRank(key: string, serverId: number) {
|
||||
* @param serverId 区服id
|
||||
* @param roleId 自己的id
|
||||
*/
|
||||
export async function getUnionRank(key: string, serverId: number, roleId: string, limit = 100) {
|
||||
export async function getUnionRank(key: string, serverId: number, roleId: string, timelen = 10, limit = 100) {
|
||||
|
||||
let ranks = [], myRank = null;
|
||||
let unionKey = await generateUnionRank(key, serverId);
|
||||
@@ -627,6 +626,38 @@ export async function getUnionRank(key: string, serverId: number, roleId: string
|
||||
return {ranks, myRank}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取(分两个zset的)排行的一段排名内的数据
|
||||
* @param key 配置在REDIS_KEY中的key
|
||||
* @param serverId 区服id
|
||||
* @param startRank 开始排名
|
||||
* @param endRank 结束排名
|
||||
*/
|
||||
export async function getUnionRankRange(key: string, serverId: number, startRank: number, endRank: number) {
|
||||
let ranks = [];
|
||||
|
||||
let unionKey = await generateUnionRank(key, serverId);
|
||||
const rankFromDb = await redisClient().zrevrangeAsync(unionKey, startRank - 1, endRank - 1, "WITHSCORES");
|
||||
|
||||
let _key = key.split(':')[0];
|
||||
let infoKey = REDIS_RANK_TO_INFO.get(_key)||REDIS_KEY.USER_INFO;
|
||||
|
||||
for(let ii = 0; ii < rankFromDb.length; ii+=2) {
|
||||
const _roleId = rankFromDb[ii];
|
||||
const _score = decodeScoreWithTime(rankFromDb[ii + 1]);
|
||||
const info = await redisClient().hgetAsync(infoKey, _roleId);
|
||||
const _userInfo = JSON.parse(info);
|
||||
const tmp = {..._userInfo, num: _score, rank: Math.floor(ii/2)+1};
|
||||
if(infoKey == REDIS_KEY.USER_INFO) {
|
||||
tmp["roleId"] = _roleId;
|
||||
} else if(infoKey == REDIS_KEY.GUILD_INFO) {
|
||||
tmp["code"] = _roleId;
|
||||
}
|
||||
ranks.push(tmp);
|
||||
}
|
||||
return ranks
|
||||
}
|
||||
|
||||
// 获取我的排名
|
||||
export async function getMyUnionRank(key: string, serverId: number, roleId: string) {
|
||||
let unionKey = await generateUnionRank(key, serverId);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { nowSeconds, getTodayZeroPoint, getAge } from '../pubUtils/timeUtil';
|
||||
import { getPvpGkWarIds, getPvpRankRewards, getPvpHeroRewards, getResultMaxRank, getTodayGuildActivity } from '../pubUtils/data';
|
||||
import { deepCopy, getRandomArr, resResult } from '../pubUtils/util';
|
||||
import { getLvByScore } from './pvpService';
|
||||
import { getMyRank, setRank, resetPvpRanks, getAllOnlineRoles, delGuildActivityRank } from './redisService';
|
||||
import { getMyRank, setRank, resetPvpRanks, getAllOnlineRoles, delGuildActivityRank, getAllServers } from './redisService';
|
||||
import { MAIL_TYPE, REDIS_KEY, ADULT_AGE, GUEST_MAX_TIME, ADDICTION_PREVENTION_CODE, GUILD_ACTIVITY_STATUS, GUILD_ACTIVITY_TYPE } from '../consts';
|
||||
import { RankParam } from '../domain/rank';
|
||||
import { RoleModel } from '../db/Role';
|
||||
@@ -24,6 +24,7 @@ import { getGuildActivityByDic, setMedianCe, sendEndMsgToAll } from './guildActi
|
||||
import { sendUngotDividendJob, startGuildAuction, startWorldAuction, stopAuction } from './auctionService';
|
||||
import { DicGuildActivity } from '../pubUtils/dictionary/DicGuildActivity';
|
||||
import { GuildModel } from '../db/Guild';
|
||||
import { dispatch } from '../util/dispatcher';
|
||||
|
||||
const PER_SECOND = 1 * 1000;
|
||||
const PER_DAY = 24 * 60 * 60;
|
||||
@@ -364,11 +365,13 @@ async function guildActivitySchedule() {
|
||||
|
||||
if(statusResult.status == GUILD_ACTIVITY_STATUS.START) {
|
||||
if(!guildActSecondsJobId) {
|
||||
let seconds = 10; // 每10秒下发一次
|
||||
if(dicGuildActivity.id == GUILD_ACTIVITY_TYPE.RACE_ACTIVITY) {
|
||||
seconds = 1;
|
||||
if(dicGuildActivity.id == GUILD_ACTIVITY_TYPE.GATE_ACTIVITY) {
|
||||
guildActSecondsJobId = scheduleJob('guildActivitySeconds', `*/10 * * * * *`, gateActivitySeconds);
|
||||
} else if(dicGuildActivity.id == GUILD_ACTIVITY_TYPE.CITY_ACTIVITY) {
|
||||
guildActSecondsJobId = scheduleJob('guildActivitySeconds', `*/10 * * * * *`, cityActivitySeconds);
|
||||
} else if(dicGuildActivity.id == GUILD_ACTIVITY_TYPE.RACE_ACTIVITY) {
|
||||
// guildActSecondsJobId = scheduleJob('guildActivitySeconds', `*/1 * * * * *`, raceActivitySeconds);
|
||||
}
|
||||
guildActSecondsJobId = scheduleJob('guildActivitySeconds', `*/${seconds} * * * * *`, gateActivitySeconds);
|
||||
}
|
||||
|
||||
if(!guildActEndJobId) {
|
||||
@@ -452,6 +455,17 @@ export async function cityActivitySeconds() {
|
||||
}
|
||||
}
|
||||
|
||||
// 每10秒下发一次的任务
|
||||
export async function raceActivitySeconds() {
|
||||
console.log('*****raveActivitySeconds')
|
||||
let servers = await getAllServers(); // 玩家serverId列表
|
||||
let guildServers = pinus.app.getServersByType('guild');
|
||||
for(let serverId of servers) {
|
||||
let sid = dispatch(serverId.toString(), guildServers);
|
||||
await pinus.app.rpc.guild.guildActivityRemote.calWoodenHorseAndSend.toServer(sid.id, serverId);
|
||||
}
|
||||
}
|
||||
|
||||
function auctionSchedule() {
|
||||
scheduleJob('startGuildAuction', '0 0 20 20 * ?', startGuildAuction);
|
||||
scheduleJob('startWorldAuction', '0 0 20 30 * ?', startWorldAuction);
|
||||
|
||||
@@ -72,11 +72,18 @@ export function guild(session: Session, msg: any, app: Application, cb: (err: Er
|
||||
'guild.cityActivityHandler.checkBattle',
|
||||
'guild.cityActivityHandler.hitGate',
|
||||
'guild.cityActivityHandler.battleEnd'
|
||||
].indexOf(arg.route) !== -1) {
|
||||
].indexOf(arg.route) !== -1) {
|
||||
|
||||
if (arg.body.cityId) {
|
||||
rid = arg.body.cityId.toString();
|
||||
}
|
||||
} else if (['guild.raceActivityHandler.getRaceActivity',
|
||||
'guild.raceActivityHandler.join',
|
||||
'guild.raceActivityHandler.getRace',
|
||||
]) {
|
||||
rid = session.get('serverId').toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ declare module 'redis' {
|
||||
// 返回有序集中指定成员的排名,从大到小
|
||||
zrevrankAsync(key: string, field: string): Promise<number>;
|
||||
// 命令返回有序集中,指定区间内的成员,从大到小
|
||||
zrevrangeAsync(key: string, start: number, end: number): Promise<string[]>;
|
||||
zrevrangeAsync(key: string, start: number, end: number, withscores?: string): Promise<string[]>;
|
||||
// 对有序集合中指定成员的分数加上增量 increment
|
||||
zincrbyAsync(key: string, increment: number, member: string): Promise<number>;
|
||||
// 对有序集合中指定成员的分数加上增量 increment
|
||||
|
||||
@@ -174,4 +174,34 @@ export enum CITY_STATUS {
|
||||
CAN_DECLARE = 1, // 可宣战
|
||||
DECLARED = 2, // 已宣战
|
||||
GUARD = 3 // 已占领
|
||||
}
|
||||
|
||||
// 粮草先行事件表
|
||||
export enum RACE_EVENT {
|
||||
LIANNU = 1, // 连弩
|
||||
GUISHOUYINFU = 2, // 鬼手阴符
|
||||
FENGCHE = 3, // 风车
|
||||
WUGUIBANYUNFU = 4, // 五鬼搬运符
|
||||
LUDUN = 5, // 橹盾
|
||||
TIANSHIDUNFU = 6, // 天师盾符
|
||||
JIASU_1 = 7, // 加速事件
|
||||
JIASU_2 = 8, // 加速事件
|
||||
HUIFU_1 = 9, // 恢复事件
|
||||
JIANSU_1 = 10, // 减速事件
|
||||
JIANSU_2 = 11, // 减速事件
|
||||
SHANGHAI_1 = 12, // 伤害事件
|
||||
ITEM = 13, // 将获得道具
|
||||
}
|
||||
|
||||
// 粮草先行事件类型
|
||||
export enum RACE_EVENT_TYPE {
|
||||
DEFAULT = 0,
|
||||
ITEM = 1, // 发道具
|
||||
EVENT = 2, // 事件
|
||||
}
|
||||
|
||||
// 粮草先行事件效果类型
|
||||
export enum RACE_EVENT_EFFECT_TYPE {
|
||||
GOOD = 1, // 好事件
|
||||
BAD = 2, // 坏事件
|
||||
}
|
||||
@@ -236,7 +236,7 @@ export const REDIS_KEY = {
|
||||
GATE_ACTIVITY: 'gateAct', // 蛮夷入侵军团排行
|
||||
USER_CITY_ACTIVITY: 'usrCityAct', // 诸侯混战玩家排行
|
||||
CITY_ACTIVITY: 'cityAct', // 诸侯混战军团排行
|
||||
|
||||
RACE_ACTIVITY: 'raceAct', // 粮草先行军团排行
|
||||
}
|
||||
|
||||
// 各排行榜对应hash的key
|
||||
@@ -247,7 +247,8 @@ export const REDIS_RANK_TO_INFO = new Map([
|
||||
[REDIS_KEY.GATE_ACTIVITY, REDIS_KEY.GUILD_INFO],
|
||||
[REDIS_KEY.USER_GATE_ACTIVITY, REDIS_KEY.USER_INFO],
|
||||
[REDIS_KEY.CITY_ACTIVITY, REDIS_KEY.GUILD_INFO],
|
||||
[REDIS_KEY.USER_CITY_ACTIVITY, REDIS_KEY.USER_INFO]
|
||||
[REDIS_KEY.USER_CITY_ACTIVITY, REDIS_KEY.USER_INFO],
|
||||
[REDIS_KEY.RACE_ACTIVITY, REDIS_KEY.GUILD_INFO]
|
||||
]);
|
||||
|
||||
export const FUNC_OPT_TYPE = {
|
||||
@@ -351,7 +352,8 @@ export const FILENAME = {
|
||||
DIC_CITY_ACTIVITY: 'dic_zyz_cityActivity',
|
||||
DIC_CHAT_ACCUSE: 'dic_zyz_chat_report',
|
||||
DIC_CHAT_SYSTEM: 'dic_zyz_chat_system',
|
||||
DIC_CITY_ACTIVITY_REWARD: 'dic_zyz_cityActivityReward'
|
||||
DIC_CITY_ACTIVITY_REWARD: 'dic_zyz_cityActivityReward',
|
||||
DIC_RACE_ACTIVITY: 'dic_zyz_raceActivity'
|
||||
}
|
||||
|
||||
export const WAR_RELATE_TABLES = [
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { GUILDACTIVITY } from "../../pubUtils/dicParam";
|
||||
import { SimpleGuildRankParam, SimpleRoleRankParam } from '../rank'
|
||||
import { SimpleGuildRankParam, SimpleRoleRankParam, GuildRankParam } from '../rank'
|
||||
import { prop } from "@typegoose/typegoose";
|
||||
import { CITY_STATUS } from "../../consts";
|
||||
import { CITY_STATUS, RACE_EVENT_TYPE, RACE_EVENT_EFFECT_TYPE, REDIS_KEY, RACE_EVENT } from "../../consts";
|
||||
import { gameData } from "../../pubUtils/data";
|
||||
import { GuildModel } from "../../db/Guild";
|
||||
import { getRandEelm, sortArrRandom } from "../../pubUtils/util";
|
||||
import { RoleType } from "../../db/Role";
|
||||
import { setRank, getMyUnionRank } from "../../services/redisService";
|
||||
import { RewardInter } from "../../pubUtils/interface";
|
||||
|
||||
export class GateMembersRec {
|
||||
roleId: string;
|
||||
@@ -208,13 +214,98 @@ export class RaceActivityObject {
|
||||
private members: Map<string, Array<Member>> = new Map(); // 每个军团参与的成员 guildCode => [{roleId, job}]
|
||||
private woodenHorses: Map<string, WoodenHorse> = new Map(); // 每个军团的木牛流马 guildCode => WoodenHorse
|
||||
private events: Map<string, Event[]> = new Map(); // 每个军团遇到的事件
|
||||
private items: Map<string, RewardInter[]> = new Map(); // 每个玩家的道具 roleId => [{id, count}]
|
||||
|
||||
getWoodenHorse(guildCode: string) {
|
||||
if(!this.woodenHorses.has(guildCode)) {
|
||||
// this.woodenHorses.set(guildCode, )
|
||||
hasJoin(guildCode: string, roleId: string) {
|
||||
let member = this.members.get(guildCode)||[];
|
||||
return member.findIndex(cur => cur.roleId == roleId) != -1;
|
||||
}
|
||||
|
||||
pushMember(guildCode: string, roleId: string, job: number) {
|
||||
if(!this.members.has(guildCode)) {
|
||||
this.members.set(guildCode, []);
|
||||
}
|
||||
let wh = this.woodenHorses.get(guildCode);
|
||||
this.members.get(guildCode).push({roleId, job});
|
||||
}
|
||||
|
||||
joinWoodenHorse(guildCode: string, roleId: string, roleName: string, job: number) {
|
||||
if(!this.woodenHorses.has(guildCode)) return false;
|
||||
let woodenHorse = this.woodenHorses.get(guildCode).joinMember(roleId, roleName);
|
||||
this.pushMember(guildCode, roleId, job);
|
||||
let events = this.events.get(guildCode)||[];
|
||||
return woodenHorse.getCurWoodenHorse(events);
|
||||
}
|
||||
|
||||
async getWoodenHorse(guildCode: string, serverId: number) {
|
||||
if(!this.woodenHorses.has(guildCode)) {
|
||||
this.initEvents(guildCode);
|
||||
let guild = await GuildModel.findByCode(guildCode, serverId);
|
||||
if(!guild) return false;
|
||||
let leader = <RoleType>guild.leader;
|
||||
let guildRankParam = new GuildRankParam(guild.icon, guild.name, guild.lv, leader);
|
||||
await setRank(REDIS_KEY.RACE_ACTIVITY, serverId, guild.code, 0, Math.pow(10, 11) - guild.guildCe, guildRankParam, true);
|
||||
let { name: guildName, guildCe } = guild;
|
||||
this.woodenHorses.set(guildCode, new WoodenHorse(guildCode, guildName, guildCe))
|
||||
}
|
||||
let woodenHorse = this.woodenHorses.get(guildCode);
|
||||
let events = this.events.get(guildCode)||[];
|
||||
return woodenHorse.getCurWoodenHorse(events);
|
||||
}
|
||||
|
||||
// 初始进入就随机9个灵球事件
|
||||
initEvents(guildCode: string) {
|
||||
if(!this.events.get(guildCode)) {
|
||||
this.events.set(guildCode, []);
|
||||
}
|
||||
let dicEncounter = gameData.raceActivityEncounter; // 距离=>事件类型
|
||||
let goodEventNum = Math.floor(dicEncounter.eventNum/2);
|
||||
let badEventNum = dicEncounter.eventNum - goodEventNum;
|
||||
|
||||
let dicRaceTypes = gameData.raceTypes.get(RACE_EVENT_TYPE.EVENT);
|
||||
let goodEvents = getRandEelm(dicRaceTypes.get(RACE_EVENT_EFFECT_TYPE.GOOD), goodEventNum);
|
||||
let badEvents = getRandEelm(dicRaceTypes.get(RACE_EVENT_EFFECT_TYPE.BAD), badEventNum);
|
||||
let events = sortArrRandom(goodEvents.concat(badEvents));
|
||||
let index = 0;
|
||||
|
||||
for(let [distance, type] of dicEncounter.events) {
|
||||
if(type == RACE_EVENT_TYPE.ITEM) {
|
||||
let event = new Event(RACE_EVENT.ITEM, guildCode, guildCode, distance);
|
||||
this.events.get(guildCode).push(event);
|
||||
} else if (type == RACE_EVENT_TYPE.EVENT) {
|
||||
let event = new Event(events[index], guildCode, guildCode, distance);
|
||||
this.events.get(guildCode).push(event);
|
||||
index ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getEvents(guildCode: string, distance: number) {
|
||||
let events = this.events.get(guildCode)||[];
|
||||
let result = new Array<Event>();
|
||||
for(let event of events) {
|
||||
let { endTime, endDistance } = event;
|
||||
if(endTime) {
|
||||
if(Date.now() > endTime) continue;
|
||||
}
|
||||
if(endDistance) {
|
||||
if(distance > endDistance) continue;
|
||||
}
|
||||
result.push(event);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
handleItem(roleId: string, id: number, inc: number) {
|
||||
let items = this.items.get(roleId)||[];
|
||||
let curItem = items.find(cur => cur.id == id);
|
||||
if(!curItem && inc < 0) return false;
|
||||
if(!curItem) {
|
||||
curItem = { id, count: 0 };
|
||||
items.push(curItem);
|
||||
}
|
||||
if(curItem.count + inc < 0 ) return false;
|
||||
curItem.count += inc;
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,15 +316,17 @@ class WoodenHorseMember {
|
||||
|
||||
// 木牛流马
|
||||
export class WoodenHorse {
|
||||
guildCode: string; // 军团code 木马的唯一标识
|
||||
guildName: string; // 军团名
|
||||
guildCe: number; // 军团战力
|
||||
speed: number; // 速度
|
||||
durability: number; // 耐久度
|
||||
distance: number; // 距离
|
||||
time: number; // 到达时间
|
||||
memberCnt: number; // 成员人数
|
||||
members: WoodenHorseMember[]; // 成员
|
||||
guildCode: string = ""; // 军团code 木马的唯一标识
|
||||
guildName: string = ""; // 军团名
|
||||
guildCe: number = 0; // 军团战力
|
||||
speed: number = 0; // 速度
|
||||
durability: number = 100; // 耐久度
|
||||
distance: number = 0; // 距离
|
||||
time: number = 0; // 到达时间
|
||||
memberCnt: number = 0; // 成员人数
|
||||
members: WoodenHorseMember[] = []; // 成员
|
||||
shield: number = 0; // 护盾数量
|
||||
shieldTime: number = 0; // 天师盾符
|
||||
|
||||
constructor(guildCode: string, guildName: string, guildCe: number) {
|
||||
this.guildCode = guildCode;
|
||||
@@ -241,23 +334,79 @@ export class WoodenHorse {
|
||||
this.guildCe = guildCe;
|
||||
}
|
||||
|
||||
calSpeed(events: Event[]) {
|
||||
let speed = this.speed;
|
||||
getCurWoodenHorse(events: Event[]) {
|
||||
this.distance += (Date.now() - this.time) * this.speed;
|
||||
let effectiveEvents = new Array<Event>();
|
||||
for(let event of events) {
|
||||
|
||||
if(!event.startTime && event.startDistance && this.distance > event.startDistance) {
|
||||
let startTime = Date.now() - Math.floor((this.distance - event.startDistance) / this.speed);
|
||||
event.setStartTime(startTime); // 距离生效的事件的实际生效时间,主要用于速度叠加顺序
|
||||
}
|
||||
let isEffective = false;
|
||||
if(event.startTime <= Date.now() && event.endTime > Date.now()) {
|
||||
isEffective = true;
|
||||
} else if (event.startDistance <= this.distance && event.endDistance > this.distance) {
|
||||
isEffective = true;
|
||||
}
|
||||
if(isEffective) {
|
||||
effectiveEvents.push(event);
|
||||
}
|
||||
}
|
||||
return speed;
|
||||
effectiveEvents.sort((a, b) => a.startTime - b.startTime);
|
||||
this.speed = this.memberCnt * 1;
|
||||
for(let { id, count, endTime } of effectiveEvents) {
|
||||
this.calEvent(id, count, endTime);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
getWoodenHorse(events: Event[]) {
|
||||
let newObj = new WoodenHorse(this.guildCode, this.guildName, this.guildCe);
|
||||
newObj.speed = this.calSpeed(events);
|
||||
newObj.durability = this.durability;
|
||||
newObj.distance = this.distance;
|
||||
newObj.time = this.time;
|
||||
newObj.memberCnt = this.memberCnt;
|
||||
newObj.members = this.members;
|
||||
return newObj;
|
||||
calEvent(id: number, count: number = 1, endTime?: number) {
|
||||
let { effect } = gameData.raceActivityEvents.get(id);
|
||||
|
||||
switch (id) {
|
||||
case RACE_EVENT.LIANNU:
|
||||
if (this.shieldTime > Date.now()) {
|
||||
if (this.shield >= count) {
|
||||
this.shield -= count;
|
||||
} else {
|
||||
this.durability -= (count - this.shield) * effect[0];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RACE_EVENT.GUISHOUYINFU:
|
||||
if (this.shieldTime > Date.now()) this.speed = 0;
|
||||
break;
|
||||
case RACE_EVENT.FENGCHE:
|
||||
case RACE_EVENT.WUGUIBANYUNFU:
|
||||
this.speed *= Math.pow(1 + effect[0] / 100, count); break;
|
||||
case RACE_EVENT.LUDUN:
|
||||
this.shield += count * effect[0]; break;
|
||||
case RACE_EVENT.TIANSHIDUNFU:
|
||||
this.shieldTime = endTime; break;
|
||||
case RACE_EVENT.JIANSU_1:
|
||||
this.speed *= 1 + effect[0]; break;
|
||||
case RACE_EVENT.JIANSU_2:
|
||||
this.speed += effect[0]; break;
|
||||
case RACE_EVENT.HUIFU_1:
|
||||
this.durability += effect[0]; break;
|
||||
case RACE_EVENT.JIANSU_1:
|
||||
this.speed *= Math.pow(1 - effect[0] / 100, count); break;
|
||||
case RACE_EVENT.JIANSU_2:
|
||||
this.speed -= effect[0]; break;
|
||||
case RACE_EVENT.SHANGHAI_1:
|
||||
this.durability -= effect[0]; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
joinMember(roleId: string, roleName: string) {
|
||||
if(this.members.findIndex(cur => cur.roleId == roleId) == -1) {
|
||||
this.members.push({ roleId, roleName });
|
||||
this.speed++;
|
||||
this.memberCnt++;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -268,9 +417,32 @@ export class Event {
|
||||
toGuild: string;
|
||||
startTime?: number;
|
||||
startDistance?: number;
|
||||
endTimestamp?: number;
|
||||
endTime?: number;
|
||||
endDistance?: number;
|
||||
effect: number[];
|
||||
count: number = 1;
|
||||
|
||||
constructor(id: number, fromGuild: string, toGuild: string, distance?: number, count?: number) {
|
||||
let dicEvent = gameData.raceActivityEvents.get(id);
|
||||
this.id = id;
|
||||
this.fromGuild = fromGuild;
|
||||
this.toGuild = toGuild;
|
||||
|
||||
if(distance) {
|
||||
this.startDistance = distance;
|
||||
this.endDistance = this.startDistance + dicEvent.continueDistance;
|
||||
}
|
||||
if(dicEvent.effectTime) {
|
||||
this.startTime = Date.now() + dicEvent.effectTime * 1000;
|
||||
this.endTime = this.startTime + dicEvent.continueTime * 1000;
|
||||
}
|
||||
if(count) {
|
||||
this.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
setStartTime(time: number) {
|
||||
this.startTime = time;
|
||||
}
|
||||
}
|
||||
|
||||
export interface GuildGateRankParam {
|
||||
|
||||
@@ -78,6 +78,17 @@ export class SimpleGuildRankParam {
|
||||
}
|
||||
}
|
||||
|
||||
export class SimpleGuildRankWithTimeParam extends SimpleGuildRankParam {
|
||||
time: number;
|
||||
durability: number;
|
||||
|
||||
constructor(rank: number, code: string, name: string, num: number, time: number, durability: number) {
|
||||
super(rank, code, name, num);
|
||||
this.time = time;
|
||||
this.durability = durability;
|
||||
}
|
||||
}
|
||||
|
||||
export class SimpleRoleRankParam {
|
||||
rank: number;
|
||||
roleId: string;
|
||||
|
||||
@@ -65,6 +65,10 @@ import { getCutDay } from "./timeUtil";
|
||||
import { dicCityActivity } from "./dictionary/DicCityActivity";
|
||||
import { dicChatAccuse } from "./dictionary/DicChatAccuse";
|
||||
import { dicCityActivityReward } from "./dictionary/DicCityActivityReward";
|
||||
import { dicRaceActivity, dicRaceTypes } from './dictionary/DicRaceActivity';
|
||||
import { GUILDACTIVITY } from "./dicParam";
|
||||
import { decodeIdCntArrayStr } from "./util";
|
||||
import { GUILD_SELECT, RACE_EVENT_TYPE } from "../consts";
|
||||
|
||||
export const gameData = {
|
||||
blurprtCompose: dicBlueprtCompose,
|
||||
@@ -152,7 +156,10 @@ export const gameData = {
|
||||
guildAuction: dicGuildAuction,
|
||||
cityActivity: dicCityActivity,
|
||||
chatAccuse: dicChatAccuse,
|
||||
cityActivityReward: dicCityActivityReward
|
||||
cityActivityReward: dicCityActivityReward,
|
||||
raceActivityEvents: dicRaceActivity,
|
||||
raceTypes: dicRaceTypes,
|
||||
raceActivityEncounter: decodeRaceActivityEncounter(),
|
||||
};
|
||||
|
||||
// 在此提供一些原先在gamedata中提供的方法,以便更方便获取gameData数据
|
||||
@@ -490,4 +497,16 @@ export function getCityActivityRewards(type: number, guildRank: number, rank: nu
|
||||
return cur.guildRank == guildRank && (rank >= cur.min && (rank <= cur.max || cur.max == 0));
|
||||
});
|
||||
return dic?dic.honour: 0;
|
||||
}
|
||||
|
||||
function decodeRaceActivityEncounter() {
|
||||
let str = GUILDACTIVITY.RACEACTIVITY_ENCOUNTER;
|
||||
let map = decodeIdCntArrayStr(str, 1);
|
||||
let newMap = new Map<number, number>();
|
||||
let eventNum = 0;
|
||||
for(let [key, value] of map) {
|
||||
if(value == RACE_EVENT_TYPE.EVENT) eventNum ++;
|
||||
newMap.set(parseInt(key), parseInt(value));
|
||||
}
|
||||
return { events: newMap, eventNum };
|
||||
}
|
||||
@@ -98,13 +98,19 @@ export const GUILDACTIVITY = {
|
||||
GATEACTIVITY_GATEHP: 10000, // 城门血量
|
||||
GATEACTIVITY_BOSS_DIFFICULT: '1&1.2|2&1.5', // boss类型&难度系数|boss类型&难度系数(1:小boss,2:大boss)
|
||||
RACEACTIVITY_DURABILITY_REWARD: 2, // 每剩余1%耐久度给予X点功勋
|
||||
RACEACTIVITY_NORMAL_ITEMS: '1&8&15|3&5&10|5&0&1', // 粮草先行普通道具
|
||||
RACEACTIVITY_EVENT_MEMBERCNT: 3, // 粮草先行随机道具获得人数
|
||||
RACEACTIVITY_EVENT_ITEMS: '2&1|4&1|6&1', // 粮草先行根据事件随机人可获得道具
|
||||
};
|
||||
export const GUILDAUCTION = {
|
||||
DIVIDENDRATE: 1, // 分红比例,1表示总金额 100% 分红
|
||||
DIVIDENDWEEKENDRATE: 0.2, // 额外分红,周末加成,0.2表示周围额外加成 20% 分红
|
||||
export const GUILD_AUCTION = {
|
||||
DIVIDEND_RATE: 1, // 总金额分红比例,1表示总金额 100% 分红
|
||||
DIVIDEND_WEEKEND_RATE: 0.2, // 额外分红,周末加成,0.2表示周围额外加成 20% 分红
|
||||
AUCTION_PRICE_RISE: 1.1, // 单次竞价价格上涨幅度,1.1表示竞拍每次价格上涨10%
|
||||
AUCTION_BOSSEXPECT_MAX: 1000, // 演武台预期分红上限
|
||||
AUCTION_BOSSEXPECT_MIN: 200, // 演武台预期分红下限
|
||||
AUCTION_ACTIVITYEXPECT_MAX: 2000, // 军团活动预期分红上限
|
||||
AUCTION_ACTIVITYEXPECT_MIN: 500, // 军团活动预期分红下限
|
||||
AUCTION_BOSS_EXPECT_MAX: 1000, // 演武台预期分红上限
|
||||
AUCTION_BOSS_EXPECT_MIN: 200, // 演武台预期分红下限
|
||||
AUCTION_ACTIVITY_EXPECT_MAX: 2000, // 军团活动预期分红上限
|
||||
AUCTION_ACTIVITY_EXPECT_MIN: 500, // 军团活动预期分红下限
|
||||
};
|
||||
export const BROWSER_DEBUG = {
|
||||
UNLIMITED_MOVEMENT: 0, // 无限行动
|
||||
};
|
||||
|
||||
46
shared/pubUtils/dictionary/DicRaceActivity.ts
Normal file
46
shared/pubUtils/dictionary/DicRaceActivity.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
// 粮草先行道具
|
||||
import { readJsonFile, parseNumberList } from '../util'
|
||||
import { FILENAME } from '../../consts'
|
||||
const _ = require('lodash');
|
||||
|
||||
export interface DicRaceActivity {
|
||||
|
||||
// 粮草先行道具id
|
||||
readonly id: number;
|
||||
// 类型 1-道具 2-事件
|
||||
readonly type: number;
|
||||
// 事件类型 1-好事件 2-坏事件
|
||||
readonly effectType: number;
|
||||
// 效果值
|
||||
readonly effect: number[];
|
||||
// 持续时间
|
||||
readonly continueTime: number;
|
||||
// 持续距离
|
||||
readonly continueDistance: number;
|
||||
// 生效时间
|
||||
readonly effectTime: number;
|
||||
|
||||
}
|
||||
|
||||
|
||||
const str = readJsonFile(FILENAME.DIC_RACE_ACTIVITY);
|
||||
let arr = JSON.parse(str);
|
||||
|
||||
type KeysEnum<T> = { [P in keyof Required<T>]: true };
|
||||
const DicRaceKeys: KeysEnum<DicRaceActivity> = {id: true, type: true, effectType: true, effect: true, continueTime: true, continueDistance: true, effectTime: true};
|
||||
|
||||
export const dicRaceActivity = new Map<number, DicRaceActivity>();
|
||||
export const dicRaceTypes = new Map<number, Map<number, number[]>>();
|
||||
|
||||
arr.forEach(o => {
|
||||
o.effectTime = o.effecttime;
|
||||
o.effect = parseNumberList(o.effect);
|
||||
dicRaceActivity.set(o.id, _.pick(o, Object.keys(DicRaceKeys)));
|
||||
if(!dicRaceTypes.has(o.type)) {
|
||||
dicRaceTypes.set(o.type, new Map<number, number[]>());
|
||||
}
|
||||
if(!dicRaceTypes.get(o.type).has(o.effectType)) {
|
||||
dicRaceTypes.get(o.type).set(o.effectType, []);
|
||||
}
|
||||
dicRaceTypes.get(o.type).get(o.effectType).push(o.id);
|
||||
});
|
||||
@@ -3,8 +3,8 @@
|
||||
"id": 1,
|
||||
"name": "汉中",
|
||||
"type": 1,
|
||||
"preCity": 0,
|
||||
"nextCity": 7,
|
||||
"preCity": 0,
|
||||
"difficult": 90,
|
||||
"warid": 7002,
|
||||
"hp": 20000
|
||||
@@ -13,8 +13,8 @@
|
||||
"id": 2,
|
||||
"name": "南中",
|
||||
"type": 1,
|
||||
"preCity": 0,
|
||||
"nextCity": 7,
|
||||
"preCity": 0,
|
||||
"difficult": 90,
|
||||
"warid": 7002,
|
||||
"hp": 20000
|
||||
@@ -23,8 +23,8 @@
|
||||
"id": 3,
|
||||
"name": "柴桑",
|
||||
"type": 1,
|
||||
"preCity": 0,
|
||||
"nextCity": 8,
|
||||
"preCity": 0,
|
||||
"difficult": 90,
|
||||
"warid": 7002,
|
||||
"hp": 20000
|
||||
@@ -33,8 +33,8 @@
|
||||
"id": 4,
|
||||
"name": "会稽",
|
||||
"type": 1,
|
||||
"preCity": 0,
|
||||
"nextCity": 8,
|
||||
"preCity": 0,
|
||||
"difficult": 90,
|
||||
"warid": 7002,
|
||||
"hp": 20000
|
||||
@@ -43,8 +43,8 @@
|
||||
"id": 5,
|
||||
"name": "太原",
|
||||
"type": 1,
|
||||
"preCity": 0,
|
||||
"nextCity": 9,
|
||||
"preCity": 0,
|
||||
"difficult": 90,
|
||||
"warid": 7002,
|
||||
"hp": 20000
|
||||
@@ -53,8 +53,8 @@
|
||||
"id": 6,
|
||||
"name": "巨鹿",
|
||||
"type": 1,
|
||||
"preCity": 0,
|
||||
"nextCity": 9,
|
||||
"preCity": 0,
|
||||
"difficult": 90,
|
||||
"warid": 7002,
|
||||
"hp": 20000
|
||||
@@ -63,40 +63,40 @@
|
||||
"id": 7,
|
||||
"name": "成都",
|
||||
"type": 2,
|
||||
"preCity": "1&2",
|
||||
"nextCity": 10,
|
||||
"preCity": "1&2",
|
||||
"difficult": 100,
|
||||
"warid": 7002,
|
||||
"warid": 7003,
|
||||
"hp": 30000
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "建业",
|
||||
"type": 2,
|
||||
"preCity": "3&4",
|
||||
"nextCity": 10,
|
||||
"preCity": "3&4",
|
||||
"difficult": 100,
|
||||
"warid": 7002,
|
||||
"warid": 7003,
|
||||
"hp": 30000
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "邺城",
|
||||
"type": 2,
|
||||
"preCity": "5&6",
|
||||
"nextCity": 10,
|
||||
"preCity": "5&6",
|
||||
"difficult": 100,
|
||||
"warid": 7002,
|
||||
"warid": 7003,
|
||||
"hp": 50000
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "洛阳",
|
||||
"type": 3,
|
||||
"preCity": "7&8&9",
|
||||
"nextCity": 0,
|
||||
"preCity": "7&8&9",
|
||||
"difficult": 110,
|
||||
"warid": 7002,
|
||||
"warid": 7004,
|
||||
"hp": 50000
|
||||
}
|
||||
]
|
||||
@@ -16,11 +16,35 @@
|
||||
"dispatchJsonId": 7002,
|
||||
"script_id": "S_7002",
|
||||
"warType": 10,
|
||||
"gk_name": "诸侯混战",
|
||||
"gk_name": "诸侯混战(小)",
|
||||
"bg_img_id": 7002,
|
||||
"lvLimted": 25,
|
||||
"turnLimted": 10,
|
||||
"victoryInfoInUI": "攻破城门",
|
||||
"loseInfoInUI": "我方全部阵亡"
|
||||
},
|
||||
{
|
||||
"war_id": 7003,
|
||||
"dispatchJsonId": 7003,
|
||||
"script_id": "S_7003",
|
||||
"warType": 10,
|
||||
"gk_name": "诸侯混战(中)",
|
||||
"bg_img_id": 7003,
|
||||
"lvLimted": 25,
|
||||
"turnLimted": 10,
|
||||
"victoryInfoInUI": "攻破城门",
|
||||
"loseInfoInUI": "我方全部阵亡"
|
||||
},
|
||||
{
|
||||
"war_id": 7004,
|
||||
"dispatchJsonId": 7004,
|
||||
"script_id": "S_7004",
|
||||
"warType": 10,
|
||||
"gk_name": "诸侯混战(大)",
|
||||
"bg_img_id": 7004,
|
||||
"lvLimted": 25,
|
||||
"turnLimted": 10,
|
||||
"victoryInfoInUI": "攻破城门",
|
||||
"loseInfoInUI": "我方全部阵亡"
|
||||
}
|
||||
]
|
||||
@@ -2,9 +2,9 @@
|
||||
{
|
||||
"id": 1,
|
||||
"name": "蛮夷入侵",
|
||||
"openDay": "4",
|
||||
"openDay": "",
|
||||
"duringTime": 900,
|
||||
"startTime": 15,
|
||||
"startTime": 16,
|
||||
"startMinute": 15,
|
||||
"countDown": 5,
|
||||
"warid": 7001,
|
||||
@@ -13,7 +13,7 @@
|
||||
{
|
||||
"id": 2,
|
||||
"name": "诸侯混战",
|
||||
"openDay": "2&6",
|
||||
"openDay": "",
|
||||
"duringTime": 900,
|
||||
"startTime": 11,
|
||||
"startMinute": 48,
|
||||
@@ -24,9 +24,9 @@
|
||||
{
|
||||
"id": 3,
|
||||
"name": "粮草先行",
|
||||
"openDay": "1&5",
|
||||
"duringTime": 600,
|
||||
"startTime": 11,
|
||||
"openDay": "1&5&6",
|
||||
"duringTime": 600000,
|
||||
"startTime": 9,
|
||||
"startMinute": 48,
|
||||
"countDown": 5,
|
||||
"warid": 0,
|
||||
|
||||
145
shared/resource/jsons/dic_zyz_raceActivity.json
Normal file
145
shared/resource/jsons/dic_zyz_raceActivity.json
Normal file
@@ -0,0 +1,145 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "连弩",
|
||||
"info": "每个造成0.2%的耐久度伤害",
|
||||
"type": 0,
|
||||
"effectType": 0,
|
||||
"effect": "0.2&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 5
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "鬼手阴符",
|
||||
"info": "使用后敌方停止移动,持续5秒",
|
||||
"type": 0,
|
||||
"effectType": 0,
|
||||
"effect": "5&",
|
||||
"continueTime": 5,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 5
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "风车",
|
||||
"info": "每个增加2%速度,持续5秒",
|
||||
"type": 0,
|
||||
"effectType": 0,
|
||||
"effect": "2&5",
|
||||
"continueTime": 5,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 5
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "五鬼搬运符",
|
||||
"info": "使用后增加40%速度,持续5秒",
|
||||
"type": 0,
|
||||
"effectType": 0,
|
||||
"effect": "40&5",
|
||||
"continueTime": 5,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 5
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "橹盾",
|
||||
"info": "使用后抵挡20次连弩攻击",
|
||||
"type": 0,
|
||||
"effectType": 0,
|
||||
"effect": "20&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 5
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "天师盾符",
|
||||
"info": "使用后免疫地方攻击,持续10秒",
|
||||
"type": 0,
|
||||
"effectType": 0,
|
||||
"effect": "10&",
|
||||
"continueTime": 10,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 0
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"name": "加速事件",
|
||||
"info": "神秘符纸,加速20%",
|
||||
"type": 2,
|
||||
"effectType": 1,
|
||||
"effect": "20&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 100,
|
||||
"effecttime": 0
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"name": "加速事件",
|
||||
"info": "将士饱食,士气高昂,加速1.5m/S",
|
||||
"type": 2,
|
||||
"effectType": 1,
|
||||
"effect": "1.5&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 100,
|
||||
"effecttime": 0
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"name": "恢复事件",
|
||||
"info": "巧匠修补,耐久度恢复15%",
|
||||
"type": 2,
|
||||
"effectType": 1,
|
||||
"effect": "15&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 0
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"name": "减速事件",
|
||||
"info": "蜀道泥泞,降速20%",
|
||||
"type": 2,
|
||||
"effectType": 2,
|
||||
"effect": "20&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 100,
|
||||
"effecttime": 0
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"name": "减速事件",
|
||||
"info": "栈道被破坏,降速1.5m/s",
|
||||
"type": 2,
|
||||
"effectType": 2,
|
||||
"effect": "1.5&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 100,
|
||||
"effecttime": 0
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"name": "伤害事件",
|
||||
"info": "滚石袭击,耐久度降低25%",
|
||||
"type": 2,
|
||||
"effectType": 2,
|
||||
"effect": "25&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 0
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"name": "添加道具事件",
|
||||
"info": "增加一定的道具",
|
||||
"type": 1,
|
||||
"effectType": 0,
|
||||
"effect": "&",
|
||||
"continueTime": 0,
|
||||
"continueDistance": 0,
|
||||
"effecttime": 0
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user