Files
ZYZ/shared/domain/battleField/guildActivity.ts
2022-07-12 11:24:13 +08:00

369 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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; // 天师盾符
remainItems: Map<number, { total: number, max: number }> = new Map();
isRobot: boolean = false; // debug接口生成
constructor(guildCode: string, guildName: string, guildCe: number, serverId: number, allStartTime: number, isRobot: boolean) {
this.guildCode = guildCode;
this.guildName = guildName;
this.guildCe = guildCe;
this.serverId = serverId;
this.allStartTime = allStartTime;
this.isRobot = isRobot;
}
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.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.BREAK;
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.time = endTime;
this.speed = effect[1];
}
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];
if(this.speed < 0) this.speed = 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() {
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;
}
needReCalHorse() {
let importantEvents = [
RACE_EVENT.LIANNU, // 连弩可能durability突然变0
RACE_EVENT.GUISHOUYINFU, // 鬼手阴符
RACE_EVENT.FENGCHE, // 风车
RACE_EVENT.WUGUIBANYUNFU, // 五鬼搬运符
];
return importantEvents.indexOf(this.id) != -1
}
}
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;
}
}