[閒聊] 拍賣場

作者: laechan (揮淚斬馬雲)   2021-08-09 15:38:01
這東西的大致構想是:
一、玩家可任意上架自己身上的東西到拍賣場。東西上架就會從
自己身上消失,而拍賣場倉庫會新增一件該物品。東西若自
己下架就會回到自己身上。衍生設定大概就是上下架費用,
或是上下架間隔(CD時間)。
二、玩家有專屬指令可瀏覽拍賣場上的所有物品,並可透過特定
的語法做篩選、過濾及排序。重點是讓玩家可輕易找到自己
想要的東西。一般來說可能做成選單式會比較好,一行指令
式的則語法可能就要類似資料庫語法。
三、在拍賣場上完成的交易,賣方可事後從拍賣場拿回$$。
相關指令不難寫,比較關鍵的是物件資料儲存的方式,假設某一
時間點,拍賣場共被上架了 1000 件物品,然後全部被儲存到一
個 .o 檔的話,那可能會太多。
這時直覺的想法是分散式儲存,例如以武防的 type 做為分類的
依據,存成 sword.o、ring.o、... 等等,而物品就存成 obj.o
,虛擬物品就存成 vobj.o 之類的。
每一個 .o 檔會有一個對應的 .c 檔,然後再一個 auction.c去
做控制:
inherit ROOM;
mapping auction;
void create()
{
object ob,*obs=([]);
string f,*dirs=([]);
seteuid(getuid(this_object()));
auction=([]);
dirs=get_dir(AUCTION_PATH);
foreach(f in dirs)
{
if(strsrch(f,".o")) continue;
f=substr(f,".c","");
ob=find_object_or_load(AUCTION_PATH+f);
auction[f]=ob->load_auction();
}
這樣比方 auction["sword"] 就載入了 sword.c 所儲存的拍賣場上
所有 sword 類武器的資料,auction["ring"] 就載入了 ring.c 所
儲存的拍賣場上所有 ring 類防具的資料。
則有了這樣一個 auction mapping 資料,自然就能對它做各種的處
理。
然後當玩家上下架、或買賣了任一 type 的東西時,僅需處理兩個東
西:
1.auction["某類物品"] 的即時資料
2.某類物品.c 下的對映資料
這兩個可寫成同一個函數來做處理即可,就不會遺漏,例如:
上架 auction_puton()
下架 auction_putoff()
賣出 auction_sell()
這樣做有個好處,就是當拍賣場物品資料有變動時,它僅只會有一個
.o 檔的資料有變動,而且這個 .o 檔的資料不大。
接下來有幾個眉角。
第一個是總合搜尋,一般來說:
一、每一筆 save 到 .o 的資料錄越精簡,整體的 .o 檔越小,但是
搜尋起來越麻煩,因為肯定是要先將該資料錄對映的物件先load
進來才能去讀取該物件的資料(比方等級、屬性、..)
二、每一筆 save 到 .o 的資料錄越完整,那搜尋起來越省力,比方
要搜尋的東西在 auction mapping 資料裡面其實就有了,那搜尋
起來自然就簡單多了,但相對的,.o 檔就得寫很大。
根據均值定理,則必存在一種方法,使得 .o 檔不會太大,要做搜尋
時亦不會太複雜,理想的情況是,唯有買賣成交的那一刻,物件才會
被實際 clone 出來給買方,其它時候則不應該 clone 出物品。
方法各家不同。
第二個是總合列表,一般來說,應避免玩家每一個下列表指令,就去
做複雜的 foreach 及字串累加及 print/more,這在拍賣場商品數量
極多的情況下會相當耗費資源。
雖然說現在主機效能都很好,mud 也支援多核心甚至多綫程,如果是
要方便撰寫的話,操一下應該也無妨。
不過寫法上還是要考慮一下。有一種做法是一開始就不允許總合式列
表,因為這基本上無意義可言,玩家固然有想看看拍賣場總共有哪些
東西的想法,但實際上真正呈現時,那其實是一個無意義的資料,資
料在做呈現時應該要有意義,例如說
> list
sword 類物品: 35 件
ring 類物品: 123 件
.
.
.
玩家進一步搜尋時
> list -type sword
羅德斯長劍(lodoss sword) 1000 int
羅德斯長劍(lodoss sword) 980 int
勇猛的雙倍力量的武士長劍(samurai sword) 11111111 int
air+5 str+40
奧瑪長劍(oma sword) 330 int
.
.
.
才顯示比較完整一點的內容。
這樣的好處是
一、只允許分類搜尋時,就能期望每一分類的數量不會過多。
二、玩家自己本來就會依自己當下的需要做分類搜尋。
三、不同分類的東西互相做比較沒有意義。
又例如它想針對有加 air 屬性的東西做列表
> list -stat air
又例如它想針對有加 str 而且 20 以上,而且是 sword 類:
> list -type sword -stat str >= 20
> list -stat str >=20 -type sword
那這個要怎麼做 sscanf 呢? 其實不難,因為 -stat、-type 都是固定
的,方法很多種,各家不同。
那以上的語法就是所謂的一行指令式,如果以資料庫語法舉例:
> select sword from auction where stat/air >= 20
而所謂的索引式指的是
> search
sword 類物品: 35 件
ring 類物品: 123 件
.
.
.
請輸入搜尋條件: type = sword
羅德斯長劍(lodoss sword) 1000 int
羅德斯長劍(lodoss sword) 980 int
勇猛的雙倍力量的武士長劍(samurai sword) 11111111 int
air+5 str+40
奧瑪長劍(oma sword) 330 int
.
.
.
請輸入搜尋條件: str >= 20
勇猛的雙倍力量的武士長劍(samurai sword) 11111111 int
air+5 str+40
.
.
.
索引式寫法以這個例子來說可能比較不複雜,但缺點是它比較難以內建
的 more 去跑,要動一點手腳;不使用內建 more 可能會有字串堆疊過
長的問題。
第三個是要能夠允許玩家把拍賣場當暫時的倉庫。則一般可以想見,身
上東西太多、自己倉庫的東西也太多的玩家,會把多餘的東西暫時往拍
賣場丟的情況,這時常用的做法有幾個
一、限制玩家上架物品的數量
二、上架收$$
三、上架的東西有時間限制,時間一到賣不掉就回到賣方身上或
  是賣方的倉庫。不過這個不一定好做
四、限制只有哪些東西可上架
以三來說,例如我今天有兩把武器,一把是商店隨便就能買到的羅德斯
長劍,一把是打怪才會掉的勇猛的雙倍力量的武士長劍,那限制玩家不
能上架羅德斯長劍是合理的,因為商店就有了,上拍賣場佔空間幹啥?
通常會看到一跟二一起實施的做法,再加個四也很合理,三則要看好不
好做以及可不可靠。
第四個是,既然叫拍賣場,玩家能否競標同一項物品?例如允許賣方不
僅可訂直購價,還可訂底標價,後者允許多名買方玩家可出價競標同一
件物品,最後價高者得之類的,但這個同樣牽涉到當買方得標但不在線
上時的得標物品處理方式,一般有三種
一、不允許競標,只允許直購,那買到的當下就買到自然沒後續問題。
二、得標的物品「暫時寄放於拍賣場」,等得標者上線領取
三、得標的物品「直接寄到玩家倉庫」,得標者上線再去自己倉庫領取
通常初期先求有再求好的情況下用一比較省事,或者多寫一個二也不難
,得標商品只要加設兩個參數即可:
auction["物品id"]["buyer"]="得標者的id";
auciton["物品id"]["already_sell"]=1;
有 already_sell 標記的物品就不會出現於任何搜尋,也無法再被下架
及購買,只有 buyer 可領取即可。
以上一點分享。sanc 應該會做,我們基本上 ready 了,玩家可打到未
鑑定防具(類似 D3 的?武防),鑑定後其相關素質才會跑出來,所以縱
使打到同一件武防,鑑定的結果也會各不相同,這時就有上拍賣場的價
值。
> searchobj snake arm
高氣力完整無瑕堅固的 蛇王臂甲(snake arm)
高氣勁完整的 蛇王臂甲(snake arm)
完整的 靈蛇臂甲(snake arm)
高魔力完整無瑕堅固的 蛇紋護臂(snake arm)
堅固的 靈蛇臂甲(snake arm)
蛇紋護臂(snake arm)
高力體完整無瑕堅固的 靈蛇臂甲(snake arm)
高魔力的 蛇紋護臂(snake arm)
高氣勁的 靈蛇臂甲(snake arm)
可能鑑定到高魔力的 蛇紋護臂(snake arm)的是戰士,它不需要這東西
,這時就可把這東西上拍賣場,並從拍賣場挑選有沒有加很多力量的。
作者: tsetsethatha (吉星麥造~~~我來了)   2021-08-09 21:33:00
感謝laechan大的文章~

Links booklink

Contact Us: admin [ a t ] ucptt.com