Skip to content

Commit

Permalink
feat: 대충 기능 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
Kimu-Nowchira committed Jan 27, 2024
1 parent 3b1d651 commit ed24080
Show file tree
Hide file tree
Showing 14 changed files with 345 additions and 37 deletions.
24 changes: 23 additions & 1 deletion src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Season } from './types/room'
import { Biome, Season } from './types/room'
import { FishRarity, StatEffect } from './types/types'

export const ROOM_TIER_EMBED_COLOR = [
Expand All @@ -25,6 +25,9 @@ export const DEFAULT_STAT_EFFECTS: StatEffect = {
expCoef: 1,
}

// 매각수수료 (주인이 있는 땅을 매입할 때 발생함)
export const SELL_FEE = 0.05

/** 이 아래는 차후 다국어 지원 시 수정해야 합니다. */

export const getSeasonName = (season: Season) => {
Expand Down Expand Up @@ -69,3 +72,22 @@ export const getFishIcon = (rarity: FishRarity) => {
return '🐋'
}
}

export const getBiomeName = (biome: Biome) => {
switch (biome) {
case Biome.Desert:
return '🏜️ 메마른 땅'
case Biome.Sea:
return '🏖️ 바닷가'
case Biome.River:
return '🏞️ 강가'
case Biome.Lake:
return '🚤 호수'
case Biome.Valley:
return '⛰️ 계곡'
case Biome.Swamp:
return '🥬 습지'
case Biome.Foreshore:
return '🦀 갯벌'
}
}
6 changes: 5 additions & 1 deletion src/models/counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ interface ICounter {
}

const counterSchema = new Schema<ICounter>({
userId: { type: mongoose.Schema.Types.ObjectId, required: true },
userId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
unique: true,
},
})

export const Counter = model<ICounter>('counters', counterSchema)
2 changes: 1 addition & 1 deletion src/models/fishData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface IFishData {
}

const fishData = new Schema<IFishData>({
id: { type: String, required: true },
id: { type: String, required: true, unique: true },
name: { type: String, required: true },
avgPrice: { type: Number, required: true },
avgLength: { type: Number, required: true },
Expand Down
9 changes: 6 additions & 3 deletions src/models/room.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DEFAULT_STAT_EFFECTS } from '../constants'
import { DEFAULT_STAT_EFFECTS, SELL_FEE } from '../constants'
import { findBuilding } from '../game/building'
import {
Biome,
Expand All @@ -16,7 +16,7 @@ import mongoose, { Schema, model } from 'mongoose'

export const roomSchema = new Schema<IRoom, IRoomMethods>(
{
id: { type: String, required: true },
id: { type: String, required: true, unique: true },
name: { type: String, required: true },

ownerId: { type: mongoose.Schema.Types.ObjectId },
Expand Down Expand Up @@ -44,7 +44,10 @@ export const roomSchema = new Schema<IRoom, IRoomMethods>(

// 매입에 필요한 최소 금액
roomSchema.methods.getMinPrices = function (this: RoomDoc): number {
return this.landPrice ? this.landPrice * 1.1 : 30000
// 주인이 있을 경우 땅값의 5%를 추가함
return this.landPrice
? this.landPrice * (1 + (this.ownerId ? SELL_FEE : 0))
: 30000
}

// 시설 효과 불러오기
Expand Down
3 changes: 1 addition & 2 deletions src/models/user.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { RoomDoc } from '../types/room'
import { IUser, IUserMethods, UserDoc, UserModel } from '../types/user'
import { Room } from './room'
import { Schema, model } from 'mongoose'

const userSchema = new Schema<IUser, IUserMethods>(
{
id: { type: String, required: true },
id: { type: String, required: true, unique: true },
username: { type: String, required: true },
money: { type: Number, required: true, default: 0 },
exp: { type: Number, required: true, default: 0 },
Expand Down
15 changes: 15 additions & 0 deletions src/modules/etc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Colors,
EmbedBuilder,
PermissionsBitField,
inlineCode,
} from 'discord.js'

class EtcExtension extends Extension {
Expand All @@ -30,6 +31,20 @@ class EtcExtension extends Extension {
) {
if (!i.channel || i.channel.isDMBased() || !i.guild?.members.me) return

// 권한 체크 (이프가 메시지 관리하기 이상의 권한을 가지고 있어야 함)
if (
!i.guild.members.me.permissions.has(
PermissionsBitField.Flags.ManageMessages
)
) {
return i.reply({
content:
'이프한테 그럴 권한이 없잖아요!\n' +
inlineCode('❗ 이프에게 메시지 관리하기 권한을 주세요'),
ephemeral: true,
})
}

// 권한 체크 (유저가 메시지 관리하기 이상의 권한을 가지고 있어야 함)
if (!i.memberPermissions?.has(PermissionsBitField.Flags.ManageMessages)) {
return i.reply({
Expand Down
4 changes: 2 additions & 2 deletions src/modules/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class InfoExtension extends Extension {
}

@applicationCommand({
name: 'info',
name: 'ep_info',
nameLocalizations: {
ko: '정보',
ko: '이프',
},
type: ApplicationCommandType.ChatInput,
description: '현재 이프의 정보를 알려줘요!',
Expand Down
5 changes: 3 additions & 2 deletions src/modules/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ class ProfileExtension extends Extension {

const profileMsgs = [
`- \`💰 소지금\` ${profile.money.toLocaleString()}원`,
`- \`💲 총 자산\` ${profile.totalPrice.toLocaleString()}원`,
`- \`⭐ 레벨\` Lv. ${
profile.level
} \`(✨ ${profile.exp.toLocaleString()} EXP)\``,
...(profile.roomCount
? [`- \`🎣 매입한 낚시터\` ${profile.roomCount}`]
? [`- \`🎣 매입한 낚시터\` ${profile.roomCount}`]
: []),
...(profile.highestRoom
? [`- \`🏠 가장 높은 땅값\` 💰 ${profile.highestRoom.name}`]
Expand Down Expand Up @@ -69,7 +70,7 @@ class ProfileExtension extends Extension {
iconURL: i.user.displayAvatarURL(),
})
.setColor(Colors.Gold)
.setDescription(`💰 ${epUser.money.toLocaleString()}`)
.setDescription(`💰 **${epUser.money.toLocaleString()}**`)
.setFooter({ text: '물고기를 낚아 더 많은 이프머니를 모아봐요!' })
.setTimestamp()

Expand Down
37 changes: 37 additions & 0 deletions src/modules/room/building.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { getRoomAnalysis } from '../../services/room/analysis'
import { roomGroup } from './index'
import { Extension } from '@pikokr/command.ts'
import {
ChatInputCommandInteraction,
Colors,
EmbedBuilder,
codeBlock,
inlineCode,
} from 'discord.js'

class BuildingExtension extends Extension {
@roomGroup.command({
name: 'buildings',
nameLocalizations: { ko: '시설' },
description:
'이 낚시터의 시설을 조회할 수 있어요! (관리자는 시설 철거도 가능)',
dmPermission: false,
})
async buildings(i: ChatInputCommandInteraction) {
if (!i.channel || i.channel.isDMBased()) return
}

@roomGroup.command({
name: 'build',
nameLocalizations: { ko: '시설건설' },
description: '이 낚시터에 시설을 건설할 수 있어요!',
dmPermission: false,
})
async info(i: ChatInputCommandInteraction) {
if (!i.channel || i.channel.isDMBased()) return
}
}

export const setup = async () => {
return new BuildingExtension()
}
72 changes: 72 additions & 0 deletions src/modules/room/changeBiome.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { getBiomeName } from '../../constants'
import { Biome } from '../../types/room'
import { roomGroup } from './index'
import { Extension, option } from '@pikokr/command.ts'
import {
APIApplicationCommandOptionChoice,
ApplicationCommandOptionType,
ChatInputCommandInteraction,
Colors,
EmbedBuilder,
} from 'discord.js'

const biomeCategories: APIApplicationCommandOptionChoice<number>[] = [
{ name: getBiomeName(Biome.Sea), value: Biome.Sea },
{ name: getBiomeName(Biome.River), value: Biome.River },
{ name: getBiomeName(Biome.Lake), value: Biome.Lake },
{ name: getBiomeName(Biome.Valley), value: Biome.Valley },
{ name: getBiomeName(Biome.Swamp), value: Biome.Swamp },
{ name: getBiomeName(Biome.Foreshore), value: Biome.Foreshore },
{ name: getBiomeName(Biome.Desert), value: Biome.Desert },
]

class ChangeBiomeExtension extends Extension {
@roomGroup.command({
name: 'change_biome',
nameLocalizations: { ko: '지형변경' },
description: '낚시터의 지형을 변경할 수 있어!',
dmPermission: false,
})
async buy(
i: ChatInputCommandInteraction,
@option({
name: 'biome',
name_localizations: { ko: '지형' },
description: '어떤 지형으로 변경할 건가요?',
type: ApplicationCommandOptionType.Integer,
choices: biomeCategories,
required: true,
})
biome: Biome
) {
if (!i.channel || i.channel.isDMBased()) return
await i.deferReply()

const room = await i.channel.epRoom
const originBiome = room.biome

if (originBiome === biome) {
return i.editReply('이미 이 낚시터의 지형이에요!')
}

room.biome = biome
await room.save()

const embed = new EmbedBuilder()
.setTitle(`🏞️ ' ${room.name} ' 낚시터 지형 변경`)
.setDescription(
[
`- \`지형\` ${getBiomeName(originBiome)}${getBiomeName(biome)}`,
`- \`지형 조성 비용\` 💰 ${(99999).toLocaleString()}`,
].join('\n')
)
.setColor(Colors.Blue)
.setTimestamp()

await i.editReply({ embeds: [embed] })
}
}

export const setup = async () => {
return new ChangeBiomeExtension()
}
7 changes: 4 additions & 3 deletions src/modules/room/info.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getSeasonIcon, getSeasonName } from '../../constants'
import { getBiomeName, getSeasonIcon, getSeasonName } from '../../constants'
import { getRoomInfo } from '../../services/room/info'
import { removeEmojis } from '../../utils/demojify'
import { roomGroup } from './index'
Expand All @@ -22,7 +22,7 @@ class RoomInfoExtension extends Extension {
if (!i.channel || i.channel.isDMBased()) return

const room = await i.channel.epRoom
const { roomThumbnail, effects } = await getRoomInfo(
const { roomThumbnail, effects, roomOwner } = await getRoomInfo(
room,
this.client,
i.guild || undefined
Expand All @@ -32,9 +32,10 @@ class RoomInfoExtension extends Extension {
.setTitle(`ℹ️ ' ${removeEmojis(room.name)} ' 낚시터 정보`)
.setDescription(
dedent`
- \`지형\` ${getBiomeName(room.biome)}
- \`계절\` ${getSeasonIcon(room.season)} ${getSeasonName(room.season)}
- \`주인\` ${
room.ownerId ? `👑 <@${room.ownerId}>` : '공영 낚시터 **(매입 가능)**'
room.ownerId ? `👑 ${roomOwner}` : '공영 낚시터 **(매입 가능)**'
}
- \`수질\` **2급수** \`(🧹 ${room.clean.toLocaleString()})\`
- \`땅값\` 💰 ${room.landPrice.toLocaleString()}
Expand Down
Loading

0 comments on commit ed24080

Please sign in to comment.