364 lines
13 KiB
TypeScript
364 lines
13 KiB
TypeScript
import { GUILDACTIVITY } from "../../pubUtils/dicParam";
|
|
import { SimpleGuildRankParam, SimpleRoleRankParam } from '../rank'
|
|
import { prop } from "@typegoose/typegoose";
|
|
import { CITY_STATUS, RACE_ACTIVITY_STATUS, RACE_EVENT } from "../../consts";
|
|
import { gameData, getRaceEventItems } from "../../pubUtils/data";
|
|
import { getRandEelm, getRandResultByMember, } from "../../pubUtils/util";
|
|
import { RewardInter } from "../../pubUtils/interface";
|
|
|
|
export class GateMembersRec {
|
|
roleId: string;
|
|
round: number = 0;
|
|
enemies: number[] = [];
|
|
constructor(roleId: string) {
|
|
this.roleId = roleId;
|
|
}
|
|
}
|
|
|
|
export class WoodenHorseMember {
|
|
roleId: string;
|
|
roleName: string;
|
|
sid: string;
|
|
items: RewardInter[] = [];
|
|
code?: string;
|
|
hasReceiveInitItems: boolean = false;
|
|
|
|
constructor(roleId: string, roleName: string, sid: string, code: string) {
|
|
this.roleId = roleId;
|
|
this.roleName = roleName;
|
|
this.sid = sid;
|
|
this.code = code;
|
|
}
|
|
|
|
addTempItem(item: RewardInter) {
|
|
this.items.push(item);
|
|
}
|
|
|
|
addTempItems(items: RewardInter[]) {
|
|
this.items.push(...items);
|
|
}
|
|
|
|
getTempItems() {
|
|
return this.items;
|
|
}
|
|
|
|
receiveTempItems() {
|
|
let items = [...this.items];
|
|
this.items = [];
|
|
return items;
|
|
}
|
|
|
|
isReceived() {
|
|
return this.hasReceiveInitItems;
|
|
}
|
|
|
|
setReceived(hasReceiveInitItems: boolean) {
|
|
this.hasReceiveInitItems = hasReceiveInitItems;
|
|
}
|
|
}
|
|
|
|
// 木牛流马
|
|
export class WoodenHorse {
|
|
@prop({required: true})
|
|
serverId: number = 0; // 服务器id
|
|
@prop({required: true})
|
|
guildCode: string = ""; // 军团code 木马的唯一标识
|
|
@prop({required: true})
|
|
guildName: string = ""; // 军团名
|
|
@prop({required: true})
|
|
guildCe: number = 0; // 军团战力
|
|
@prop({required: true})
|
|
status: number = 0; // 状态 0-停止 1-开启 2-结束
|
|
@prop({required: true})
|
|
speed: number = GUILDACTIVITY.RACE_INIT_SPEED; // 速度
|
|
@prop({required: true})
|
|
durability: number = 100; // 耐久度
|
|
@prop({required: true})
|
|
distance: number = 0; // 距离
|
|
@prop({required: true})
|
|
allStartTime: number = 0; // 全服开启世界
|
|
@prop({required: true})
|
|
startTime: number = 0; // 开始时间
|
|
@prop({required: true})
|
|
time: number = 0; // 到达时间
|
|
@prop({required: true})
|
|
memberCnt: number = 0; // 成员人数
|
|
@prop({required: true})
|
|
members: WoodenHorseMember[] = []; // 成员
|
|
@prop({required: true})
|
|
shield: number = 0; // 护盾数量
|
|
@prop({required: true})
|
|
shieldTime: number = 0; // 天师盾符
|
|
@prop({required: true})
|
|
stopContinueTime: number = 0; // 鬼手阴符
|
|
|
|
remainItems: Map<number, { total: number, max: number }> = new Map();
|
|
|
|
constructor(guildCode: string, guildName: string, guildCe: number, serverId: number, allStartTime: number) {
|
|
this.guildCode = guildCode;
|
|
this.guildName = guildName;
|
|
this.guildCe = guildCe;
|
|
this.serverId = serverId;
|
|
this.allStartTime = allStartTime;
|
|
}
|
|
|
|
public startRace(allStartTime: number) {
|
|
this.status = RACE_ACTIVITY_STATUS.START;
|
|
this.time = Date.now();
|
|
this.startTime = Date.now();
|
|
this.allStartTime = allStartTime;
|
|
}
|
|
|
|
/**
|
|
* 根据时间计算当前木马速度距离耐久等
|
|
* @param events
|
|
* @returns {boolean} needSendEnd 是否跑到终点发送结束新号
|
|
*/
|
|
public calCurWoodenHorse(events: Event[]): boolean {
|
|
if(this.status == RACE_ACTIVITY_STATUS.END) return false;
|
|
if(this.status == RACE_ACTIVITY_STATUS.PAUSE && this.stopContinueTime && Date.now() > this.stopContinueTime) {
|
|
this.status = RACE_ACTIVITY_STATUS.START; this.stopContinueTime = 0;
|
|
}
|
|
|
|
if(this.status == RACE_ACTIVITY_STATUS.START) {
|
|
if(this.distance >= GUILDACTIVITY.RACEACTIVITY_LENGTH) {
|
|
this.distance = GUILDACTIVITY.RACEACTIVITY_LENGTH;
|
|
this.status = RACE_ACTIVITY_STATUS.END;
|
|
this.speed = 0;
|
|
return true;
|
|
}
|
|
|
|
this.distance = Math.floor((this.distance + (Date.now() - this.time)/1000 * this.speed ) * 1000)/1000; // 1位小数点
|
|
this.time = Date.now();
|
|
}
|
|
let effectiveEvents = new Array<Event>();
|
|
for(let i = 0; i < events.length; i++) {
|
|
let event = events[i];
|
|
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;
|
|
} else if (event.endTime < Date.now() || event.endDistance < this.distance) {
|
|
if(event.endTime && event.startTime == event.endTime) {
|
|
isEffective = true;
|
|
}
|
|
if(event.endDistance && event.startDistance == event.endDistance) {
|
|
isEffective = true;
|
|
}
|
|
|
|
let index = events.findIndex(cur => cur.id == event.id);
|
|
events.splice(index, 1);
|
|
}
|
|
if(isEffective) {
|
|
effectiveEvents.push(event);
|
|
}
|
|
}
|
|
|
|
effectiveEvents.sort((a, b) => a.startTime - b.startTime);
|
|
this.speed = GUILDACTIVITY.RACE_INIT_SPEED + this.memberCnt * GUILDACTIVITY.RACE_PER_SPEED;
|
|
for(let { id, count, endTime } of effectiveEvents) {
|
|
this.calEvent(id, count, endTime);
|
|
}
|
|
if(this.durability <= 0) {
|
|
this.status = RACE_ACTIVITY_STATUS.END;
|
|
this.speed = 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private 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.shield = 0;
|
|
this.durability -= (count - this.shield) * effect[0];
|
|
if(this.durability > 100) this.durability = 100;
|
|
if(this.durability < 0) this.durability = 0;
|
|
}
|
|
}
|
|
break;
|
|
case RACE_EVENT.GUISHOUYINFU:
|
|
if (this.shieldTime < Date.now()) {
|
|
this.stopContinueTime = endTime;
|
|
this.status = RACE_ACTIVITY_STATUS.PAUSE;
|
|
this.time = endTime;
|
|
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.JIASU_1:
|
|
this.speed *= Math.pow(1 + effect[0] / 100, count); break;
|
|
case RACE_EVENT.JIASU_2:
|
|
this.speed += effect[0]; break;
|
|
case RACE_EVENT.HUIFU_1:
|
|
this.durability += effect[0];
|
|
if(this.durability > 100) this.durability = 100;
|
|
if(this.durability < 0) this.durability = 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];
|
|
if(this.durability > 100) this.durability = 100;
|
|
if(this.durability < 0) this.durability = 0;
|
|
break;
|
|
case RACE_EVENT.ITEM:
|
|
let ranMember: WoodenHorseMember[] = getRandEelm(this.members, GUILDACTIVITY.RACEACTIVITY_EVENT_MEMBERCNT);
|
|
if(ranMember.length <= 0) ranMember = this.members;
|
|
for(let member of ranMember) {
|
|
let item = gameData.raceEventItems;
|
|
member.addTempItems(item);
|
|
}
|
|
let normalItems = getRaceEventItems();
|
|
for(let [id, {total, max}] of normalItems) {
|
|
let randResult = getRandResultByMember(total, max, this.members.length);
|
|
for(let i = 0; i < this.members.length; i++) {
|
|
let count = randResult.arr[i]||0;
|
|
if(count > 0) {
|
|
this.members[i].addTempItem({ id, count });
|
|
normalItems.get(id).total -= count;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
public joinMember(roleId: string, roleName: string, sid: string, code: string) {
|
|
let index = this.members.findIndex(cur => cur.roleId == roleId)
|
|
if(index == -1) {
|
|
let member = new WoodenHorseMember(roleId, roleName, sid, code);
|
|
this.members.push(member);
|
|
this.speed++;
|
|
this.memberCnt++;
|
|
return member;
|
|
} else {
|
|
return this.members[index];
|
|
}
|
|
}
|
|
|
|
public setRemainItem(id: number, remain: number, max: number) {
|
|
this.remainItems.set(id, { total: remain, max });
|
|
}
|
|
|
|
public getTreatTime() {
|
|
console.log('#######', this.time, this.allStartTime)
|
|
return {...this, time: this.time - this.allStartTime }
|
|
}
|
|
|
|
}
|
|
|
|
export class Event {
|
|
@prop({required: true})
|
|
id: number;
|
|
@prop({required: true})
|
|
fromGuild: string;
|
|
@prop({required: true})
|
|
toGuild: string;
|
|
@prop({required: true})
|
|
startTime?: number;
|
|
@prop({required: true})
|
|
startDistance?: number;
|
|
@prop({required: true})
|
|
endTime?: number;
|
|
@prop({required: true})
|
|
endDistance?: number;
|
|
@prop({required: true})
|
|
count: number = 1;
|
|
|
|
constructor(id: number, fromGuild: string, toGuild: string, count?: number, distance?: 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 GuildRankParams {
|
|
guildRank: SimpleGuildRankParam[],
|
|
myGuildRank: SimpleGuildRankParam,
|
|
memberRank?: SimpleRoleRankParam[],
|
|
myMemberRank?: SimpleRoleRankParam
|
|
}
|
|
|
|
export class Member {
|
|
@prop({required: true})
|
|
roleId: string; // 玩家id
|
|
@prop({required: true})
|
|
job: number; // 在军团的职位
|
|
@prop({required: false})
|
|
code?: string; // 玩家的当前记录的code
|
|
}
|
|
|
|
export class CityParam {
|
|
cityId: number = 0; // 城池id
|
|
guardGuildCode: string = ''; // 占领军团id
|
|
guardGuildName: string = ''; // 占领军团名
|
|
declareCount: number = 0; // 宣战数
|
|
status: number = CITY_STATUS.NOT_OPEN; // 城池对于我军状态
|
|
|
|
constructor(cityId: number) {
|
|
this.cityId = cityId;
|
|
}
|
|
}
|
|
|
|
export class RaceActivityRankParam {
|
|
rank: number = 0;
|
|
code: string;
|
|
name: string;
|
|
time: number;
|
|
sortTime: number;
|
|
sortDistance: number;
|
|
num: number;
|
|
durability: number;
|
|
|
|
constructor(woodenHorse: WoodenHorse) {
|
|
this.code = woodenHorse.guildCode;
|
|
this.name = woodenHorse.guildName;
|
|
this.durability = woodenHorse.durability;
|
|
let distance = woodenHorse.distance > 1000? 1000: woodenHorse.distance;
|
|
this.sortDistance = distance;
|
|
this.sortTime = woodenHorse.time - woodenHorse.allStartTime;
|
|
this.num = Math.floor(distance);
|
|
this.time = Math.floor((woodenHorse.time - woodenHorse.allStartTime)/1000)
|
|
}
|
|
|
|
setRank(rank: number) {
|
|
this.rank = rank;
|
|
}
|
|
} |