作者itoc.bbs@processor.tfcis.org (核心動力) 看板: plan
標題[功能] RPG 架構
時間動力核心 (2004/08/23 Mon 23:15:43) Updated: 2004/10/09
新增此功能以後
舊使用者要先 (A)pply RPG申請,才會有 RPG 帳號
新使用者則是在註冊時就會順便填 RPG 帳號
: maple.p
+ /* rpg.c */
+ int rpg_load(RPG *rpg, char *userid);
+ void rpg_save(RPG *rpg, char *userid);
+ void rpg_apply(RPG *u, char *userid);
+ int r_info(void);
+ int r_query(void);
+ int r_apply(void);
: bbsd.c:u_exit()
/* 寫回 .ACCT */
if (!HAS_STATUS(STATUS_DATALOCK))
{
...
...
close(fd);
}
+ rpg_save(&crpg, cuser.userid);
}
}
: bbsd.c:acct_apply()
+ rpg_apply(&crpg, userid);
+ usr_fpath(buf, userid, FN_RPG);
+ fd = open(buf, O_WRONLY | O_CREAT, 0600);
+ write(fd, &crpg, sizeof(crpg));
+ close(fd);
sprintf(buf, "%d", try);
blog("APPLY", buf);
: bbsd.c:login_user()
+ rpg_load(&crpg, uid);
return multi;
}
: menu.c:menu_rpg[] 新增在 menu_tool[] 上面
/* --------------------------------------------------- */
/* rpg menu */
/* --------------------------------------------------- */
static MENU menu_rpg[] =
{
r_query, 0, M_QUERY,
"Query RPG查詢",
r_info, PERM_BASIC, M_XMODE,
"Info RPG資訊",
r_apply, PERM_BASIC, M_XMODE,
"Apply RPG申請",
menu_tool, PERM_MENU + 'Q', M_XMENU,
"冒險進取"
};
: menu.c:menu_tool[]
+ menu_rpg, 0, M_XMENU,
+ "RPG 【 遊戲人間 】",
menu_tool, PERM_MENU + Ctrl('A'), M_XMENU,
"其他功\能"
: bbs.h
#include "struct.h" /* data structure */
+ #include "rpg.h" /* rule play game */
#include "global.h" /* global variable & definition */
: global.h
/* ----------------------------------------------------- */
/* 個人目錄檔名設定 */
/* ----------------------------------------------------- */
+ #define FN_RPG ".RPG" /* User rpg account */
#define FN_ACCT ".ACCT" /* User account */
...
...
/* ----------------------------------------------------- */
/* GLOBAL VARIABLE */
/* ----------------------------------------------------- */
+ VAR RPG crpg; /* current user structure */
VAR int bbsmode; /* bbs operating mode, see modes.h */
: src/maple/Makefile
SRC = acct.c bbsd.c bmw.c board.c cache.c edit.c favor.c \
gem.c mail.c menu.c more.c pal.c post.c talk.c visio.c \
- window.c xover.c xpost.c
+ window.c xover.c xpost.c rpg.c
OBJ = acct.o bbsd.o bmw.o board.o cache.o edit.o favor.o \
gem.o mail.o menu.o more.o pal.o post.o talk.o visio.o \
- window.o xover.o xpost.o
+ window.o xover.o xpost.o rpg.o
: ─────────────────────────────────────
: src/include/rpg.h 新增此程式
: 其中 struct RPG 只是個範例,可以隨自己的遊戲設定修改
/*-------------------------------------------------------*/
/* rpg.h ( NTHU CS MapleBBS Ver 3.10 ) */
/*-------------------------------------------------------*/
/* target : rpg games */
/* create : 00/03/16 */
/* update : / / */
/* author : itoc.bbs@bbs.tnfsh.tn.edu.tw */
/*-------------------------------------------------------*/
#ifndef _RPG_H_
#define _RPG_H_
/*-------------------------------------------------------*/
/* 參考 struct.h */
/* ----------------------------------------------------- */
/* 使用者遊戲記錄 .RPG struct : 512 bytes */
/* ----------------------------------------------------- */
typedef struct
{
char usertitle[12]; /* 頭銜 */
char username[24]; /* 暱稱 */
int level; /* 等級(絕對值) (+)轉職後的等級 (-)轉職前的等級 */
int alliance; /* 陣營(絕對值) (+)善良 (-)邪惡 */
int exp; /* 經驗值 */
/* 能量(用2char縮寫) */
int hp; /* 體力 health point */
int mp; /* 靈力 mana point */
int mv; /* 動力 moving point */
int po; /* 內力 power point */
/* 能量上限 */
int maxhp; /* 血 */
int maxmp; /* 靈力 */
int maxmv; /* 動力 */
int maxpo; /* 內力 */
/* 屬性(用3char縮寫) */
int str; /* 力量 strength */
int inl; /* 智力 intelligence */
int wis; /* 智慧 wisdom */
int dex; /* 敏捷 dexterity */
int con; /* 體格 constitution */
int luc; /* 運氣 luck */
int cha; /* 魅力 charisma */
/* 隱藏特質(用4char縮寫) */
int calm; /* 冷靜 calm */
int cour; /* 勇氣 courage */
int heal; /* 健康 health */
int lern; /* 學習 learn */
int mood; /* 心情 mood */
/* 五大資源(用單數) */
int money; /* 銀幣 */
int gold; /* 黃金 */
int gem; /* 寶石 */
int wood; /* 木材 */
int iron; /* 礦石 */
/* 十大裝備(用單數) */
int weapon; /* 武器 */
int helm; /* 頭盔、帽、冠 */
int amulet; /* 護身符、項鍊 */
int armor; /* 盔甲 */
int glove; /* 手套 */
int ring; /* 戒指 */
int bracer; /* 臂章 */
int belt; /* 皮帶 */
int pant; /* 褲子 */
int shoe; /* 鞋子 */
} RPG;
#endif /* _RPG_H_ */
: ─────────────────────────────────────
: src/maple/rpg.c 新增此程式
/*-------------------------------------------------------*/
/* rpg.c ( NTHU CS MapleBBS Ver 3.00 ) */
/*-------------------------------------------------------*/
/* target : rpg routines */
/* create : 01/03/16 */
/* update : / / */
/* author : itoc.bbs@bbs.tnfsh.tn.edu.tw */
/*-------------------------------------------------------*/
#include "bbs.h"
/* ----------------------------------------------------- */
/* (.RPG) 冒險者帳號 (account) I/O */
/* ----------------------------------------------------- */
int
rpg_load(rpg, userid)
RPG *rpg;
char *userid;
{
int fd;
usr_fpath((char *) rpg, userid, FN_RPG);
fd = open((char *) rpg, O_RDONLY);
if (fd >= 0)
{
/* Thor.990416: 特別注意, 有時 .RPG的長度會是0 */
read(fd, rpg, sizeof(RPG));
close(fd);
}
return fd;
}
void
rpg_save(rpg, userid)
RPG *rpg;
char *userid;
{
int fd;
char fpath[64];
usr_fpath(fpath, userid, FN_RPG);
fd = open(fpath, O_WRONLY | O_CREAT, 0600);
if (fd >= 0)
{
write(fd, rpg, sizeof(RPG));
close(fd);
}
}
/* ----------------------------------------------------- */
/* (.RPG) 冒險者帳號 (account) subroutine */
/* ----------------------------------------------------- */
void
rpg_apply(u, userid)
RPG *u;
char *userid;
{
strcpy(u->usertitle, "新冒險者");
strcpy(u->username, userid);
u->level = -1;
u->alliance = u->exp = 0;
u->hp = u->mp = u->mv = u->po =
u->maxhp = u->maxmp = u->maxmv = u->maxpo = 100;
u->str = u->inl = u->wis = u->dex = u->con = u->luc = u->cha = 10;
u->calm = u->cour = u->heal = u->lern = u->mood = 0;
u->money = u->gold = u->gem = u->wood = u->iron = 0;
u->weapon = u->helm = u->amulet = u->armor = u->glove = 0;
u->ring = u->bracer = u->belt = u->pant = u->shoe = 0;
}
static int
rpg_get(msg, rpg, userid)
char *msg;
RPG *rpg;
char *userid;
{
outz("★ 輸入首字母後, 可以按空白鍵自動搜尋");
/* --------------------------------------------------- */
/* name complete for user ID */
/* --------------------------------------------------- */
/* return value : */
/* 0: 使用直接按 enter ==> cancel */
/* -1: bad user id */
/* 1: current user id */
/* --------------------------------------------------- */
if (!vget(1, 0, msg, userid, IDLEN + 1, GET_USER))
return 0;
if (rpg_load(rpg, userid) >= 0)
return 1;
vmsg(err_uid);
return -1;
}
static void
rpg_show(u, adm)
RPG *u;
int adm; /* 0: user info/query 1: admin */
{
int alli;
char *camp;
clrtobot();
outs("\n \033[30;41m┬┴┬┴┬┴\033[m \033[45m╰╦╦╮╭╦═╮"
"╔╦═╮╭╦═╮\033[m \033[30;41m┬┴┬┴┬┴\033[m\n"
" \033[30;41m┴┬┴┬┴┬\033[m \033[1;37;45m ╠╣ ╠╣"
" ║╠╬╣ ╠╣ ║\033[m \033[30;41m┴┬┴┬┴┬\033[m\n"
" \033[30;41m┬┴┬┴┬┴\033[m \033[45m ╠╣ ╠╣ ║"
"╠╣╯ ╠╣ ║\033[m \033[30;41m┬┴┬┴┬┴\033[m\n"
" \033[30;41m┴┬┴┬┴┬\033[m \033[1;30;45m╰╩╩╮╚╝"
" ╰╚╝ ╰╩═╯\033[m \033[30;41m┴┬┴┬┴┬\033[m\n");
alli = u->alliance;
if (alli > 100)
{
if (alli > 700)
camp = "\033[41m大好人\033[m";
else if (alli > 400)
camp = "\033[1;31m好人\033[m";
else
camp = "\033[31m有一點點善良\033[m";
}
else if (alli < -100)
{
if (alli < -700)
camp = "\033[45m你實在太壞了\033[m";
else if (alli < -400)
camp = "\033[1;35m蠻賤的\033[m";
else
camp = "\033[35m有一點點邪惡\033[m";
}
else
camp = "中立無比";
prints("\n能量:體力 %5d/%5d 靈力 %5d/%5d 動力 %5d/%5d 內力 %5d/%5d\n",
u->hp, u->maxhp, u->mp, u->maxmp, u->mv, u->maxmv, u->po, u->maxpo);
prints("\n\033[1;33m[%s] \033[36m%s\033[m",
u->usertitle, u->username);
prints("\n考核:等級 %5d 經驗 %5d 陣營 %s %s轉職",
abs(u->level), u->exp, camp, u->level > 0 ? "已" : "未");
prints("\n屬性:力量 [%3d] 智力 [%3d] 智慧 [%3d] 敏捷 [%3d]",
u->str, u->inl, u->wis, u->dex);
prints("\n屬性:體格 [%3d] 運氣 [%3d] 魅力 [%3d]",
u->con, u->luc, u->cha);
prints("\n資源:銀幣 %5d 黃金 %5d", u->money, u->gold);
prints("\n資源:寶石 %5d 木材 %5d 礦石 %5d", u->gem, u->wood, u->iron);
if (adm)
{
prints("\n特質:冷靜 %5d 勇氣 %5d 健康 %5d 學習 %5d 心情 %5d",
u->calm, u->cour, u->heal, u->lern, u->mood);
prints("\n裝備:武器 %5d 頭盔 %5d 項鍊 %5d 盔甲 %5d 手套 %5d",
u->weapon, u->helm, u->amulet, u->armor, u->glove);
prints("\n裝備:戒指 %5d 臂章 %5d 皮帶 %5d 褲子 %5d 鞋子 %5d",
u->ring, u->bracer, u->belt, u->pant, u->shoe);
}
outs("\n\n \033[30;41m┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬┴┬"
"┴┬┴┬┴┬┴┬┴┬┴┬\033[m");
}
static void
rpg_setup(u, userid, adm)
RPG *u;
char *userid;
int adm;
{
RPG x;
int i, num;
char *str, buf[80];
rpg_show(u, adm);
memcpy(&x, u, sizeof(RPG));
if (vans("設定 1)資料 Q)取消 [Q] ") != '1')
return;
move(i = 3, 0);
clrtobot();
str = x.usertitle;
while (1)
{
if (vget(i, 0, "頭 銜:", str, sizeof(x.usertitle), GCARRY))
break;
}
i++;
str = x.username;
while (1)
{
if (vget(i, 0, "暱 稱:", str, sizeof(x.username), GCARRY))
break;
}
if (adm)
{
for (;;)
{
/* 還有改別的欄位的話,自己改寫程式 */
adm = vans("1)等級 2)陣營 3)上限 [Q] ");
if (adm == '1')
{
sprintf(buf, "%d", u->level);
vget(i, 0, "等級:", buf, 6, GCARRY);
x.level = atoi(buf);
}
else if (adm == '2')
{
sprintf(buf, "%d", u->alliance);
vget(i, 0, "陣營:", buf, 6, GCARRY);
x.alliance = atoi(buf);
}
else if (adm == '3')
{
for (;;)
{
num = vans("[上限] s)力量 i)智力 w)智慧 d)敏捷 "
"c)體格 l)運氣 a)魅力 [Q] ");
if (num == 's')
{
sprintf(buf, "%d", u->str);
vget(i, 0, "力量:", buf, 6, GCARRY);
if (num = atoi(buf) > 0)
x.str = num;
}
else if (num == 'i')
{
sprintf(buf, "%d", u->inl);
vget(i, 0, "智力:", buf, 6, GCARRY);
if (num = atoi(buf) > 0)
x.inl = num;
}
else if (num == 'w')
{
sprintf(buf, "%d", u->wis);
vget(i, 0, "智慧:", buf, 6, GCARRY);
if (num = atoi(buf) > 0)
x.wis = num;
}
else if (num == 'd')
{
sprintf(buf, "%d", u->dex);
vget(i, 0, "敏捷:", buf, 6, GCARRY);
if (num = atoi(buf) > 0)
x.dex = num;
}
else if (num == 'c')
{
sprintf(buf, "%d", u->con);
vget(i, 0, "體格:", buf, 6, GCARRY);
if (num = atoi(buf) > 0)
x.con = num;
}
else if (num == 'l')
{
sprintf(buf, "%d", u->luc);
vget(i, 0, "運氣:", buf, 6, GCARRY);
if (num = atoi(buf) > 0)
x.luc = num;
}
else if (num == 'a')
{
sprintf(buf, "%d", u->cha);
vget(i, 0, "魅力:", buf, 6, GCARRY);
if (num = atoi(buf) > 0)
x.cha = num;
}
else
{
break;
}
}
}
else
{
break;
}
}
}
if (vans(msg_sure_ny) != 'y')
return;
memcpy(u, &x, sizeof(x));
rpg_save(u, userid);
utmp_admset(acct_userno(userid), STATUS_DATALOCK);
}
/* ----------------------------------------------------- */
/* 選單指令 */
/* ----------------------------------------------------- */
int
r_info()
{
move(1, 0);
rpg_setup(&crpg, cuser.userid, 0);
return 0;
}
int
r_query()
{
int ans;
char userid[IDLEN + 1];
RPG rpg;
move(1, 0);
clrtobot();
if (HAS_PERM(PERM_ALLACCT))
{
while (ans = rpg_get(msg_uid, &rpg, userid))
{
if (ans > 0)
rpg_setup(&rpg, userid, 1);
}
}
else
{
while (ans = rpg_get(msg_uid, &rpg, userid))
{
if (ans > 0)
rpg_show(&rpg, 0);
}
}
return 0;
}
int
r_apply() /* 自殺重來 */
{
if (vans("您將重新開始一段新的旅途(Y/N)?[N] ") != 'y')
return XEASY;
rpg_apply(&crpg, cuser.userid);
rpg_save(&crpg, cuser.userid);
return 0;
}
: ─────────────────────────────────────
這只是 RPG 的架構,細節並沒有寫
遊戲的細部玩法則是要讓站長自行規劃,例如:
一、發表文章,依字數加木材、依時間加礦石
: post.c:do_post()
mode = BMIN(wordsnum, spendtime) / 10; /* 每十字/秒 一元 */
prints("這是您的第 %d 篇文章,得 %d 銀。", ++cuser.numposts, mode);
addmoney(mode);
+ crpg.wood += wordsnum;
+ crpg.iron += spendtime;
二、發表文章,若字數超過時間,陣營變善良;反之變邪惡
: post.c:do_post()
mode = BMIN(wordsnum, spendtime) / 10; /* 每十字/秒 一元 */
prints("這是您的第 %d 篇文章,得 %d 銀。", ++cuser.numposts, mode);
addmoney(mode);
+ crpg.alliance += wordsnum - spendtime;
三、在水球列表丟水球,加力量
: bmw.c:bmw_write()
if (up = utmp_find(userno))
+ {
do_write(up);
+ crpg.str++;
+ }
四、在使用者列表丟水球,加智力
: ulist.c:ulist_write()
if (up = ulist_pool[xo->pos])
+ {
do_write(up);
+ crpg.inl++;
+ }
五、離站時,每一分鐘加經驗值 1 點,集滿 10000 分鐘升一級
: bbsd.c:u_exit()
diff = (time(&cuser.lastlogin) - ap_start) / 60;
+ crpg.exp += diff;
+ if (crpg.exp >= 10000)
+ {
+ crpg.exp -= 10000;
+ crpg.level++;
+ }
反正都是 crpg.xxx 怎樣怎樣
至於 xxx 是什麼,你只要看 rpg.h 就可以知道了
--
╭┼ Origin: Maple-itoc˙動力核心 processor.tfcis.org
┼┘ Author: itoc 從 itoc.dorm11.nctu.edu.tw 發表精華選讀←離開[主題上]主題下(k)上篇(j)下篇S/a搜尋 G串列 TAB精華 ↑↓捲 Pg/Space翻