forked from devsam/core
feat: 유산포인트로 장수 소유자 확인
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\InheritAction;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\APIRecoveryType;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Enums\RankColumn;
|
||||
use sammo\GameConst;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Message;
|
||||
use sammo\MessageTarget;
|
||||
use sammo\RootDB;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\UserLogger;
|
||||
use sammo\Validator;
|
||||
|
||||
use function sammo\GetImageURL;
|
||||
use function sammo\getNationStaticInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* 유산 포인트 1000 포인트를 사용하면 지정한 상대의 본래 유저명을 확인 가능.
|
||||
* 개인 메시지로 전달되며, 이 기능이 사용되었음을 상대에게도 알림.
|
||||
*/
|
||||
class CheckOwner extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', [
|
||||
'destGeneralID',
|
||||
])
|
||||
->rule('int', 'destGeneralID')
|
||||
->rule('min', 'destGeneralID', 1);
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag): null|string|array|APIRecoveryType
|
||||
{
|
||||
$userID = $session->userID;
|
||||
$generalID = $session->generalID;
|
||||
|
||||
$destGeneralID = $this->args['destGeneralID'];
|
||||
if ($generalID == $destGeneralID) {
|
||||
return '자신의 정보는 확인할 수 없습니다.';
|
||||
}
|
||||
|
||||
$general = General::createObjFromDB($generalID);
|
||||
if ($userID != $general->getVar('owner')) {
|
||||
return '로그인 상태가 이상합니다. 다시 로그인해 주세요.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$destRawGeneral = $db->queryFirstRow('SELECT no,name,nation,owner,owner_name,imgsvr,picture FROM general WHERE no = %i', $destGeneralID);
|
||||
|
||||
if (!$destRawGeneral) {
|
||||
return '대상 장수가 존재하지 않습니다.';
|
||||
}
|
||||
|
||||
if (!$destRawGeneral['owner']) {
|
||||
return '대상 장수는 NPC입니다.';
|
||||
}
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
if ($gameStor->isunited) {
|
||||
return '이미 천하가 통일되었습니다.';
|
||||
}
|
||||
|
||||
$reqPoint = GameConst::$inheritCheckOwnerPoint;
|
||||
|
||||
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||
if ($previousPoint < $reqPoint) {
|
||||
return '충분한 유산 포인트를 가지고 있지 않습니다.';
|
||||
}
|
||||
|
||||
$userLogger = new UserLogger($userID);
|
||||
$userLogger->push("{$reqPoint} 포인트로 장수 소유자 확인", "inheritPoint");
|
||||
$userLogger->flush();
|
||||
|
||||
$destGeneralName = $destRawGeneral['name'];
|
||||
$destGeneralOwnerName = $destRawGeneral['owner_name'];
|
||||
if (!$destGeneralOwnerName) {
|
||||
$rootDB = RootDB::db();
|
||||
$destGeneralOwnerName = $rootDB->queryFirstField('SELECT name FROM member WHERE no = %i', $destRawGeneral['owner']) ?? '알수없음';
|
||||
}
|
||||
|
||||
$src = new MessageTarget(0, '', 0, 'System', '#000000');
|
||||
|
||||
if (true) {
|
||||
$staticNation = $general->getStaticNation();
|
||||
$dest = new MessageTarget(
|
||||
$generalID,
|
||||
$general->getName(),
|
||||
$general->getNationID(),
|
||||
$staticNation['name'],
|
||||
$staticNation['color'],
|
||||
GetImageURL($general->getVar('imgsvr'), $general->getVar('picture'))
|
||||
);
|
||||
$msg = new Message(
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
"{$destGeneralName}의 소유자는 {$destGeneralOwnerName} 입니다.",
|
||||
new \DateTime(),
|
||||
new \DateTime('9999-12-31'),
|
||||
[]
|
||||
);
|
||||
$msg->send(true);
|
||||
}
|
||||
|
||||
$inheritStor->setValue('previous', [$previousPoint - $reqPoint, null]);
|
||||
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $reqPoint);
|
||||
$general->applyDB($db);
|
||||
|
||||
if(true){
|
||||
$destStaticNation = getNationStaticInfo($destRawGeneral['nation']);
|
||||
$dest = new MessageTarget(
|
||||
$destGeneralID,
|
||||
$destGeneralName,
|
||||
$destRawGeneral['nation'],
|
||||
$destStaticNation['name'],
|
||||
$destStaticNation['color'],
|
||||
GetImageURL($destRawGeneral['imgsvr'], $destRawGeneral['picture'])
|
||||
);
|
||||
$msg = new Message(
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
"소유자명이 누군가에 의해 확인되었습니다.",
|
||||
new \DateTime(),
|
||||
new \DateTime('9999-12-31'),
|
||||
[]
|
||||
);
|
||||
$msg->send(true);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -224,6 +224,7 @@ class GameConstBase
|
||||
public static $inheritBuffPoints = [0, 200, 600, 1200, 2000, 3000];
|
||||
public static $inheritSpecificSpecialPoint = 4000;
|
||||
public static $inheritResetAttrPointBase = [1000, 1000, 2000, 3000];//필요하면 늘려서 쓰기
|
||||
public static $inheritCheckOwnerPoint = 1000;
|
||||
|
||||
/** @var ?string */
|
||||
public static $scenarioEffect = null;
|
||||
|
||||
+93
-71
@@ -1,25 +1,17 @@
|
||||
<template>
|
||||
<TopBackBar :title="title" />
|
||||
<div
|
||||
id="container"
|
||||
class="bg0 px-2"
|
||||
style="max-width: 1000px; margin: auto; border: solid 1px #888888; overflow: hidden"
|
||||
>
|
||||
<div id="container" class="bg0 px-2"
|
||||
style="max-width: 1000px; margin: auto; border: solid 1px #888888; overflow: hidden">
|
||||
<div id="inheritance_list" class="row">
|
||||
<template v-for="(text, key) in inheritanceViewText" :key="key">
|
||||
<div :id="`inherit_${key}`" class="col col-sm-4 col-12 inherit_item inherit_template_item">
|
||||
<div class="row">
|
||||
<label :id="`inherit_${key}_head`" class="inherit_head col col-lg-6 col-sm-7 col-6 col-form-label">{{
|
||||
text.title
|
||||
}}</label>
|
||||
text.title
|
||||
}}</label>
|
||||
<div class="col col-lg-6 col-sm-5 col-6">
|
||||
<input
|
||||
:id="`inherit_${key}_value`"
|
||||
type="text"
|
||||
class="form-control inherit_value f_tnum"
|
||||
readonly
|
||||
:value="Math.floor(items[key]).toLocaleString()"
|
||||
/>
|
||||
<input :id="`inherit_${key}_value`" type="text" class="form-control inherit_value f_tnum" readonly
|
||||
:value="Math.floor(items[key]).toLocaleString()" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -53,13 +45,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="a-right">
|
||||
<small class="form-text text-muted"
|
||||
><!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<small class="form-text text-muted"><!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<span style="color: white" v-html="availableSpecialWar[nextSpecialWar].info" /><br />다음에 얻을 전투
|
||||
특기를 정합니다.<br /><span style="color: white"
|
||||
>필요 포인트: {{ inheritActionCost.nextSpecial }}</span
|
||||
></small
|
||||
>
|
||||
특기를 정합니다.<br /><span style="color: white">필요 포인트: {{ inheritActionCost.nextSpecial }}</span></small>
|
||||
</div>
|
||||
<div class="row px-4">
|
||||
<BButton class="col-6 offset-6" variant="primary" @click="setNextSpecialWar"> 구입 </BButton>
|
||||
@@ -79,17 +67,12 @@
|
||||
</div>
|
||||
<div class="row px-4">
|
||||
<div class="col f_tnum">
|
||||
<NumberInputWithInfo
|
||||
v-model="specificUniqueAmount"
|
||||
title="입찰 포인트"
|
||||
:min="inheritActionCost.minSpecificUnique"
|
||||
:max="items.previous"
|
||||
/>
|
||||
<NumberInputWithInfo v-model="specificUniqueAmount" title="입찰 포인트"
|
||||
:min="inheritActionCost.minSpecificUnique" :max="items.previous" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="a-right">
|
||||
<small class="form-text text-muted"
|
||||
>얻고자 하는 유니크 아이템으로 경매를 시작합니다. 24턴 동안 진행됩니다.<br />
|
||||
<small class="form-text text-muted">얻고자 하는 유니크 아이템으로 경매를 시작합니다. 24턴 동안 진행됩니다.<br />
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<span style="color: white" v-html="specificUnique == null ? '' : availableUnique[specificUnique].info" />
|
||||
</small>
|
||||
@@ -110,11 +93,8 @@
|
||||
<BButton class="col-6" variant="primary" @click="tryResestTurnTime()"> 구입 </BButton>
|
||||
</div>
|
||||
<div class="a-right">
|
||||
<small class="form-text text-muted"
|
||||
>다다음턴부터 시간이 랜덤하게 바뀝니다. (필요 포인트가 피보나치식으로 증가합니다)<br /><span style="color: white"
|
||||
>필요 포인트: {{ inheritActionCost.resetTurnTime }}</span
|
||||
></small
|
||||
>
|
||||
<small class="form-text text-muted">다다음턴부터 시간이 랜덤하게 바뀝니다. (필요 포인트가 피보나치식으로 증가합니다)<br /><span
|
||||
style="color: white">필요 포인트: {{ inheritActionCost.resetTurnTime }}</span></small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-lg-4 col-sm-6 col-12 py-2">
|
||||
@@ -123,11 +103,8 @@
|
||||
<BButton class="col-6" variant="primary" @click="buySimple('BuyRandomUnique')"> 구입 </BButton>
|
||||
</div>
|
||||
<div class="a-right">
|
||||
<small class="form-text text-muted"
|
||||
>다음 턴에 랜덤 유니크를 얻습니다.<br /><span style="color: white"
|
||||
>필요 포인트: {{ inheritActionCost.randomUnique }}</span
|
||||
></small
|
||||
>
|
||||
<small class="form-text text-muted">다음 턴에 랜덤 유니크를 얻습니다.<br /><span style="color: white">필요 포인트: {{
|
||||
inheritActionCost.randomUnique }}</span></small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-lg-4 col-sm-6 col-12 py-2">
|
||||
@@ -136,11 +113,9 @@
|
||||
<BButton class="col-6" variant="primary" @click="buySimple('ResetSpecialWar')"> 구입 </BButton>
|
||||
</div>
|
||||
<div class="a-right">
|
||||
<small class="form-text text-muted"
|
||||
>즉시 전투 특기를 초기화합니다. (필요 포인트가 피보나치식으로 증가합니다)<br /><span style="color: white"
|
||||
>필요 포인트: {{ inheritActionCost.resetSpecialWar }}</span
|
||||
></small
|
||||
>
|
||||
<small class="form-text text-muted">즉시 전투 특기를 초기화합니다. (필요 포인트가 피보나치식으로 증가합니다)<br /><span
|
||||
style="color: white">필요
|
||||
포인트: {{ inheritActionCost.resetSpecialWar }}</span></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -153,33 +128,48 @@
|
||||
<div class="row">
|
||||
<label class="col col-sm-6 col-form-label" :for="`buff-${buffKey}`">{{ info.title }}</label>
|
||||
<div class="col col-sm-6 f_tnum">
|
||||
<b-form-input
|
||||
:id="`buff-${buffKey}`"
|
||||
v-model.number="inheritBuff[buffKey]"
|
||||
type="number"
|
||||
:min="prevInheritBuff[buffKey] ?? 0"
|
||||
:max="maxInheritBuff"
|
||||
/>
|
||||
<b-form-input :id="`buff-${buffKey}`" v-model.number="inheritBuff[buffKey]" type="number"
|
||||
:min="prevInheritBuff[buffKey] ?? 0" :max="maxInheritBuff" />
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: right">
|
||||
<small class="form-text text-muted f_tnum"
|
||||
>{{ info.info }}<br /><span style="color: white"
|
||||
>필요 포인트:
|
||||
<small class="form-text text-muted f_tnum">{{ info.info }}<br /><span style="color: white">필요 포인트:
|
||||
{{
|
||||
inheritActionCost.buff[inheritBuff[buffKey]] - inheritActionCost.buff[prevInheritBuff[buffKey] ?? 0]
|
||||
}}</span
|
||||
></small
|
||||
>
|
||||
inheritActionCost.buff[inheritBuff[buffKey]] - inheritActionCost.buff[prevInheritBuff[buffKey] ?? 0]
|
||||
}}</span></small>
|
||||
</div>
|
||||
<div class="row px-4" style="margin-bottom: 1em">
|
||||
<BButton
|
||||
variant="secondary"
|
||||
class="col col-lg-6 col-4 offset-lg-0 offset-4"
|
||||
@click="inheritBuff[buffKey] = prevInheritBuff[buffKey] ?? 0"
|
||||
>
|
||||
리셋 </BButton
|
||||
><BButton variant="primary" class="col col-lg-6 col-4" @click="buyInheritBuff(buffKey)"> 구입 </BButton>
|
||||
<BButton variant="secondary" class="col col-lg-6 col-4 offset-lg-0 offset-4"
|
||||
@click="inheritBuff[buffKey] = prevInheritBuff[buffKey] ?? 0">
|
||||
리셋 </BButton>
|
||||
<BButton variant="primary" class="col col-lg-6 col-4" @click="buyInheritBuff(buffKey)"> 구입 </BButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="width: 100%; padding: 0 10px">
|
||||
<hr :style="{ opacity: 0.5 }" />
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col col-lg-4 col-sm-6 col-12 py-2">
|
||||
<div class="row px-4">
|
||||
<div class="a-right col-6 align-self-center">장수 소유자 확인</div>
|
||||
<div class="col-6">
|
||||
<select v-model="targetOwner" class="form-select col-6">
|
||||
<option disabled selected :value="null">장수 선택</option>
|
||||
<option v-for="(name, key) in availableTargetGeneral" :key="key" :value="key">
|
||||
{{ name }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="a-right">
|
||||
<small class="form-text text-muted">장수의 소유자를 찾습니다.<br />
|
||||
</small>
|
||||
<span style="color: white">필요 포인트: {{ inheritActionCost.checkOwner }}</span>
|
||||
</div>
|
||||
|
||||
<div class="row px-4">
|
||||
<BButton class="col-6 offset-6" variant="primary" @click="checkOwner"> 소유자 찾기 </BButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -196,7 +186,9 @@
|
||||
{{ log.text }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-grid"><BButton @click="getMoreLog()">더 가져오기</BButton></div>
|
||||
<div class="d-grid">
|
||||
<BButton @click="getMoreLog()">더 가져오기</BButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -231,6 +223,7 @@ declare const staticValues: {
|
||||
randomUnique: number;
|
||||
nextSpecial: number;
|
||||
minSpecificUnique: number;
|
||||
checkOwner: number;
|
||||
};
|
||||
resetTurnTimeLevel: number;
|
||||
resetSpecialWarLevel: number;
|
||||
@@ -252,6 +245,7 @@ declare const staticValues: {
|
||||
info: string;
|
||||
}
|
||||
>;
|
||||
availableTargetGeneral: Record<number, string>;
|
||||
};
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
@@ -394,6 +388,7 @@ const {
|
||||
currentInheritBuff: prevInheritBuff,
|
||||
availableSpecialWar,
|
||||
availableUnique,
|
||||
availableTargetGeneral,
|
||||
} = staticValues;
|
||||
|
||||
const nextSpecialWar = ref(Object.keys(availableSpecialWar)[0]);
|
||||
@@ -450,7 +445,7 @@ async function buyInheritBuff(buffKey: inheritBuffType) {
|
||||
location.reload();
|
||||
}
|
||||
|
||||
async function tryResestTurnTime(){
|
||||
async function tryResestTurnTime() {
|
||||
const cost = inheritActionCost.resetTurnTime;
|
||||
|
||||
if (items.value.previous < cost) {
|
||||
@@ -586,16 +581,43 @@ async function openUniqueItemAuction() {
|
||||
location.reload();
|
||||
}
|
||||
|
||||
async function getMoreLog(): Promise<void>{
|
||||
try{
|
||||
const targetOwner = ref<string | null>(null);
|
||||
|
||||
async function checkOwner(): Promise<void> {
|
||||
if (targetOwner.value === null) {
|
||||
alert("장수를 선택해주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
const targetName = availableTargetGeneral[parseInt(targetOwner.value)];
|
||||
|
||||
if (!confirm(`${targetName}의 소유자를 찾겠습니까? 대상에게도 알림이 전송됩니다.`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await SammoAPI.InheritAction.CheckOwner({
|
||||
destGeneralID: parseInt(targetOwner.value)
|
||||
});
|
||||
alert('결과가 개인 메시지로 전송되었습니다.');
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert(`실패했습니다: ${e}`);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function getMoreLog(): Promise<void> {
|
||||
try {
|
||||
const result = await SammoAPI.InheritAction.GetMoreLog({
|
||||
lastID: lastLogID.value
|
||||
});
|
||||
for(const log of result.log){
|
||||
for (const log of result.log) {
|
||||
inheritPointLogs.value.set(log.id, log);
|
||||
lastLogID.value = Math.min(lastLogID.value, log.id);
|
||||
}
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
alert(`실패했습니다: ${e}`);
|
||||
return;
|
||||
@@ -616,4 +638,4 @@ async function getMoreLog(): Promise<void>{
|
||||
.tnum {
|
||||
font-feature-settings: "tnum";
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
+4
-1
@@ -179,7 +179,10 @@ const apiRealPath = {
|
||||
}>,
|
||||
GetMoreLog: GET as APICallT<{
|
||||
lastID: number
|
||||
}, InheritLogResponse>
|
||||
}, InheritLogResponse>,
|
||||
CheckOwner: PUT as APICallT<{
|
||||
destGeneralID: number;
|
||||
}>,
|
||||
},
|
||||
Message: {
|
||||
DeleteMessage: PATCH as APICallT<{
|
||||
|
||||
@@ -16,7 +16,10 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$me = General::createObjFromDB($generalID);
|
||||
|
||||
|
||||
$availableTargetGeneral = [];
|
||||
foreach ($db->query('SELECT no, name FROM general WHERE npc < 2') as $row) {
|
||||
$availableTargetGeneral[$row['no']] = $row['name'];
|
||||
}
|
||||
|
||||
$currentInheritBuff = [];
|
||||
foreach ($me->getAuxVar('inheritBuff') ?? [] as $buff => $buffLevel) {
|
||||
@@ -95,10 +98,12 @@ $lastInheritPointLogs = $db->query('SELECT id, server_id, year, month, date, tex
|
||||
'randomUnique' => GameConst::$inheritItemRandomPoint,
|
||||
'nextSpecial' => GameConst::$inheritSpecificSpecialPoint,
|
||||
'minSpecificUnique' => GameConst::$inheritItemUniqueMinPoint,
|
||||
'checkOwner' => GameConst::$inheritCheckOwnerPoint,
|
||||
],
|
||||
'availableSpecialWar' => $avilableSpecialWar,
|
||||
'availableUnique' => $availableUnique,
|
||||
'lastInheritPointLogs' => $lastInheritPointLogs,
|
||||
'availableTargetGeneral' => $availableTargetGeneral,
|
||||
]
|
||||
]) ?>
|
||||
</head>
|
||||
|
||||
Reference in New Issue
Block a user