军团活动:粮草先行部分计算逻辑
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user