[闲聊] 拍卖场

楼主: 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