summaryrefslogtreecommitdiffstats
path: root/mbbsd/chicken.c
diff options
context:
space:
mode:
Diffstat (limited to 'mbbsd/chicken.c')
-rw-r--r--mbbsd/chicken.c1138
1 files changed, 0 insertions, 1138 deletions
diff --git a/mbbsd/chicken.c b/mbbsd/chicken.c
deleted file mode 100644
index 4de2bb85..00000000
--- a/mbbsd/chicken.c
+++ /dev/null
@@ -1,1138 +0,0 @@
-/* $Id$ */
-#include "bbs.h"
-
-// TODO pull chicken out of userec.
-// remove chickenpk.
-
-#define NUM_KINDS 15 /* 有多少種動物 */
-#define CHICKENLOG "etc/chicken"
-
-// enable if you want to run live upgrade
-// #define CHICKEN_LIVE_UPGRADE
-
-static const char * const cage[17] = {
- "誕生", "週歲", "幼年", "少年", "青春", "青年",
- "青年", "活力", "壯年", "壯年", "壯年", "中年",
- "中年", "老年", "老年", "老摳摳", "古希"};
-static const char * const chicken_type[NUM_KINDS] = {
- "小雞", "美少女", "勇士", "蜘蛛",
- "恐龍", "老鷹", "貓", "蠟筆小新",
- "狗狗", "惡魔", "忍者", "ㄚ扁",
- "馬英九", "就可人", "蘿莉"};
-static const char * const chicken_food[NUM_KINDS] = {
- "雞飼料", "營養厚片", "雞排便當", "死蝴蝶",
- "屍體", "小雞", "貓餅乾", "小熊餅乾",
- "寶錄", "靈氣", "飯團", "便當",
- "雞腿", "笑話文章", "水果沙拉"};
-static const int egg_price[NUM_KINDS] = {
- 5, 25, 30, 40,
- 80, 50, 15, 35,
- 17, 100, 85, 200,
- 200, 100, 77};
-static const int food_price[NUM_KINDS] = {
- 4, 6, 8, 10,
- 12, 12, 5, 6,
- 5, 20, 15, 23,
- 23, 10, 19};
-static const char * const attack_type[NUM_KINDS] = {
- "啄", "鞭打", "槌", "咬",
- "撞擊", "啄", "抓", "踢",
- "咬", "燃燒", "暗擊", "棍打",
- "劍擊", "冷凍光線", "香吻一枚"};
-
-static const char * const damage_degree[] = {
- "蚊子似的", "騷癢似的", "小力的", "輕微的",
- "有點疼的", "使力的", "傷人的", "重重的",
- "使全力的", "惡狠狠的", "危險的", "瘋狂的",
- "猛烈的", "狂風暴雨似的", "驚天動地的",
- "致命的", NULL};
-
-enum {
- OO, FOOD, WEIGHT, CLEAN, RUN, ATTACK, BOOK, HAPPY, SATIS,
- TEMPERAMENT, TIREDSTRONG, SICK, HP_MAX, MM_MAX
-};
-
-static const short time_change[NUM_KINDS][14] =
-/* 補品 食物 體重 乾淨 敏捷 攻擊力 知識 快樂 滿意 氣質 疲勞 病氣 滿血 滿法 */
-{
- /* 雞 */
- {1, 1, 30, 3, 8, 3, 3, 40, 9, 1, 7, 3, 30, 1},
- /* 美少女 */
- {1, 1, 110, 1, 4, 7, 41, 20, 9, 25, 25, 7, 110, 15},
- /* 勇士 */
- {1, 1, 200, 5, 4, 10, 33, 20, 15, 10, 27, 1, 200, 9},
- /* 蜘蛛 */
- {1, 1, 10, 5, 8, 1, 1, 5, 3, 1, 4, 1, 10, 30},
- /* 恐龍 */
- {1, 1, 1000, 9, 1, 13, 4, 12, 3, 1, 200, 1, 1000, 3},
- /* 老鷹 */
- {1, 1, 90, 7, 10, 7, 4, 12, 3, 30, 20, 5, 90, 20},
- /* 貓 */
- {1, 1, 30, 5, 5, 6, 4, 8, 3, 15, 7, 4, 30, 21},
- /* 蠟筆小新 */
- {1, 1, 100, 9, 7, 7, 20, 50, 10, 8, 24, 4, 100, 9},
- /* 狗 */
- {1, 1, 45, 8, 7, 9, 3, 40, 20, 3, 9, 5, 45, 1},
- /* 惡魔 */
- {1, 1, 45, 10, 11, 11, 5, 21, 11, 1, 9, 5, 45, 25},
- /* 忍者 */
- {1, 1, 45, 2, 12, 10, 25, 1, 1, 10, 9, 5, 45, 26},
- /* 阿扁 */
- {1, 1, 150, 4, 8, 13, 95, 25, 7, 10, 25, 5, 175, 85},
- /* 馬英九 */
- {1, 1, 147, 2, 10, 10, 85, 20, 4, 25, 25, 5, 145, 95},
- /* 就可人 */
- {1, 1, 200, 3, 15, 15, 50, 50, 10, 5, 10, 2, 300, 0},
- /* 羅利 */
- {1, 1, 80, 2, 9, 10, 2, 5, 7, 8, 12, 1, 135, 5},
-};
-
-static void time_diff(chicken_t * thechicken);
-static int isdeadth(const chicken_t * thechicken, chicken_t *mychicken);
-
-chicken_t * load_live_chicken(const char *uid)
-{
- char fn[PATHLEN];
- int fd = 0;
- chicken_t *p = NULL;
-
- if (!uid || !uid[0]) return NULL;
- sethomefile(fn, uid, FN_CHICKEN);
- if (!dashf(fn)) return NULL;
- fd = open(fn, O_RDWR);
- if (fd < 0) return NULL;
-
- // now fd is valie. open and mmap.
- p = mmap(NULL, sizeof(chicken_t), PROT_READ|PROT_WRITE, MAP_SHARED,
- fd, 0);
- close(fd);
- return p;
-}
-
-int load_chicken(const char *uid, chicken_t *mychicken)
-{
- char fn[PATHLEN];
- int fd = 0;
-
- memset(mychicken, 0, sizeof(chicken_t));
- if (!uid || !uid[0]) return 0;
- sethomefile(fn, uid, FN_CHICKEN);
- if (!dashf(fn)) return 0;
- fd = open(fn, O_RDONLY);
- if (fd < 0) return 0;
- if (read(fd, mychicken, sizeof(chicken_t)) > 0 && mychicken->name[0])
- return 1;
- return 0;
-}
-
-void free_live_chicken(chicken_t *p)
-{
- if (!p) return;
- munmap(p, sizeof(chicken_t));
-}
-
-void
-chicken_query(const char *userid)
-{
- chicken_t xchicken;
-
-#ifdef CHICKEN_LIVE_UPGRADE
- // live update
- vmsg("PTT 系統進行更新,本週暫停開放寵物查詢。");
- return;
-#endif
-
- if (!load_chicken(userid, &xchicken))
- {
- move(1, 0);
- clrtobot();
- prints("\n\n%s 並沒有養寵物..", userid);
- } else {
- time_diff(&xchicken);
- if (!isdeadth(&xchicken, NULL))
- {
- show_chicken_data(&xchicken, NULL);
- prints("\n\n以上是 %s 的寵物資料..", userid);
- } else {
- move(1, 0);
- clrtobot();
- prints("\n\n%s 的寵物死掉了...", userid);
- }
- }
-
- pressanykey();
-}
-
-static int
-new_chicken(void)
-{
- chicken_t mychicken;
- int price, i;
- int fd;
- char fn[PATHLEN];
-
- memset(&mychicken, 0, sizeof(chicken_t));
-
- clear();
- move(2, 0);
- outs("歡迎光臨 " ANSI_COLOR(33) "◎" ANSI_COLOR(37;44) " "
- BBSMNAME "寵物市場 " ANSI_COLOR(33;40) "◎" ANSI_RESET ".. "
- "目前蛋價:\n"
- "(a)小雞 $5 (b)美少女 $25 (c)勇士 $30 (d)蜘蛛 $40 "
- "(e)恐龍 $80\n"
- "(f)老鷹 $50 (g)貓 $15 (h)蠟筆小新$35 (i)狗狗 $17 "
- "(j)惡魔 $100\n"
- "(k)忍者 $85 (n)就可人$100 (m)蘿莉 $77\n"
- "[0]不想買了 $0\n");
- i = getans("請選擇你要養的動物:");
-
- // since (o) is confusing to some people, we alias 'm' to 'o'.
- if (i == 'm') i = 'o';
-
- // (m, l) were political person.
- // do not make them in a BBS system...
- if (i == 'm' || i == 'l')
- return 0;
-
- i -= 'a';
- if (i < 0 || i > NUM_KINDS - 1)
- return 0;
-
- mychicken.type = i;
-
- price = egg_price[(int)mychicken.type];
- reload_money();
- if (cuser.money < price) {
- vmsgf("錢不夠買蛋蛋,蛋蛋要 %d 元", price);
- return 0;
- }
-
- while (strlen(mychicken.name) < 3)
- {
- getdata(8, 0, "幫牠取個好名字:", mychicken.name,
- sizeof(mychicken.name), DOECHO);
- }
-
- mychicken.lastvisit = mychicken.birthday = mychicken.cbirth = now;
- mychicken.food = 0;
- mychicken.weight = time_change[(int)mychicken.type][WEIGHT] / 3;
- mychicken.clean = 0;
- mychicken.run = time_change[(int)mychicken.type][RUN];
- mychicken.attack = time_change[(int)mychicken.type][ATTACK];
- mychicken.book = time_change[(int)mychicken.type][BOOK];
- mychicken.happy = time_change[(int)mychicken.type][HAPPY];
- mychicken.satis = time_change[(int)mychicken.type][SATIS];
- mychicken.temperament = time_change[(int)mychicken.type][TEMPERAMENT];
- mychicken.tiredstrong = 0;
- mychicken.sick = 0;
- mychicken.hp = time_change[(int)mychicken.type][WEIGHT];
- mychicken.hp_max = time_change[(int)mychicken.type][WEIGHT];
- mychicken.mm = 0;
- mychicken.mm_max = 0;
-
- reload_money();
- if (cuser.money < price)
- {
- vmsg("錢不夠了。");
- return 0;
- }
- vice(price, "寵物蛋");
-
- // flush it
- setuserfile(fn, FN_CHICKEN);
- fd = open(fn, O_WRONLY|O_CREAT, 0666);
- if (fd < 0)
- {
- vmsg("系統錯誤: 無法建立資料,請至 " GLOBAL_BUGREPORT " 報告。");
- return 0;
- }
-
- write(fd, &mychicken, sizeof(chicken_t));
- close(fd);
-
- // log data
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s " ANSI_RESET "養了一隻叫" ANSI_COLOR(33) " %s " ANSI_RESET "的 "
- ANSI_COLOR(32) "%s" ANSI_RESET " 於 %s\n", cuser.userid,
- mychicken.name, chicken_type[(int)mychicken.type], ctime4(&now));
- return 1;
-}
-
-static void
-show_chicken_stat(const chicken_t * thechicken, int age)
-{
- struct tm *ptime;
-
- ptime = localtime4(&thechicken->birthday);
- prints(" Name :" ANSI_COLOR(33) "%s" ANSI_RESET " (" ANSI_COLOR(32) "%s" ANSI_RESET ")%*s生日 "
- ":" ANSI_COLOR(31) "%02d" ANSI_RESET "年" ANSI_COLOR(31) "%2d" ANSI_RESET "月" ANSI_COLOR(31) "%2d" ANSI_RESET "日 "
- "(" ANSI_COLOR(32) "%s %d歲" ANSI_RESET ")\n"
- " 體:" ANSI_COLOR(33) "%5d/%-5d" ANSI_RESET " 法:" ANSI_COLOR(33) "%5d/%-5d" ANSI_RESET " 攻擊力:"
- ANSI_COLOR(33) "%-7d" ANSI_RESET " 敏捷 :" ANSI_COLOR(33) "%-7d" ANSI_RESET " 知識 :" ANSI_COLOR(33) "%-7d"
- ANSI_RESET " \n"
- " 快樂 :" ANSI_COLOR(33) "%-7d " ANSI_RESET " 滿意 :" ANSI_COLOR(33) "%-7d " ANSI_RESET " 疲勞 :"
- ANSI_COLOR(33) "%-7d" ANSI_RESET " 氣質 :" ANSI_COLOR(33) "%-7d " ANSI_RESET "體重 :"
- ANSI_COLOR(33) "%-5.2f" ANSI_RESET " \n"
- " 病氣 :" ANSI_COLOR(33) "%-7d " ANSI_RESET " 乾淨 :" ANSI_COLOR(33) "%-7d " ANSI_RESET " 食物 :"
- ANSI_COLOR(33) "%-7d" ANSI_RESET " 大補丸:" ANSI_COLOR(33) "%-7d" ANSI_RESET " 藥品 :" ANSI_COLOR(33) "%-7d"
- ANSI_RESET " \n",
- thechicken->name, chicken_type[(int)thechicken->type],
- strlen(thechicken->name) >= 15 ? 0 : (int)(15 - strlen(thechicken->name)), "",
- ptime->tm_year % 100, ptime->tm_mon + 1, ptime->tm_mday,
- cage[age > 16 ? 16 : age], age, thechicken->hp, thechicken->hp_max,
- thechicken->mm, thechicken->mm_max,
- thechicken->attack, thechicken->run, thechicken->book,
- thechicken->happy, thechicken->satis, thechicken->tiredstrong,
- thechicken->temperament,
- ((float)(thechicken->hp_max + (thechicken->weight / 50))) / 100,
- thechicken->sick, thechicken->clean, thechicken->food,
- thechicken->oo, thechicken->medicine);
-}
-
-#define CHICKEN_PIC "etc/chickens"
-
-static void
-show_chicken_picture(const char *fpath)
-{
- show_file(fpath, 5, 14, SHOWFILE_ALLOW_ALL);
-}
-
-void
-show_chicken_data(chicken_t * thechicken, chicken_t * pkchicken)
-{
- char buf[1024];
- int age = ((now - thechicken->cbirth) / (60 * 60 * 24));
- if (age < 0) {
- thechicken->birthday = thechicken->cbirth = now - 10 * (60 * 60 * 24);
- age = 10;
- }
- /* Ptt:debug */
- thechicken->type %= NUM_KINDS;
- clear();
- showtitle(pkchicken ? BBSMNAME2 "鬥雞場" : BBSMNAME2 "養雞場", BBSName);
- move(1, 0);
-
- show_chicken_stat(thechicken, age);
-
- snprintf(buf, sizeof(buf), CHICKEN_PIC "/%c%d", thechicken->type + 'a',
- age > 16 ? 16 : age);
-
- show_chicken_picture(buf);
-
- move(18, 0);
-
- if (thechicken->sick)
- outs("生病了...");
- if (thechicken->sick > thechicken->hp / 5)
- outs(ANSI_COLOR(5;31) "擔心...病重!!" ANSI_RESET);
-
- if (thechicken->clean > 150)
- outs(ANSI_COLOR(31) "又臭又髒的.." ANSI_RESET);
- else if (thechicken->clean > 80)
- outs("有點髒..");
- else if (thechicken->clean < 20)
- outs(ANSI_COLOR(32) "很乾淨.." ANSI_RESET);
-
- if (thechicken->weight > thechicken->hp_max * 4)
- outs(ANSI_COLOR(31) "快飽死了!." ANSI_RESET);
- else if (thechicken->weight > thechicken->hp_max * 3)
- outs(ANSI_COLOR(32) "飽嘟嘟.." ANSI_RESET);
- else if (thechicken->weight < (thechicken->hp_max / 4))
- outs(ANSI_COLOR(31) "快餓死了!.." ANSI_RESET);
- else if (thechicken->weight < (thechicken->hp_max / 2))
- outs("餓了..");
-
- if (thechicken->tiredstrong > thechicken->hp * 1.7)
- outs(ANSI_COLOR(31) "累得昏迷了..." ANSI_RESET);
- else if (thechicken->tiredstrong > thechicken->hp)
- outs("累了..");
- else if (thechicken->tiredstrong < thechicken->hp / 4)
- outs(ANSI_COLOR(32) "精力旺盛..." ANSI_RESET);
-
- if (thechicken->hp < thechicken->hp_max / 4)
- outs(ANSI_COLOR(31) "體力用盡..奄奄一息.." ANSI_RESET);
- if (thechicken->happy > 500)
- outs(ANSI_COLOR(32) "很快樂.." ANSI_RESET);
- else if (thechicken->happy < 100)
- outs("不快樂..");
- if (thechicken->satis > 500)
- outs(ANSI_COLOR(32) "很滿足.." ANSI_RESET);
- else if (thechicken->satis < 50)
- outs("不滿足..");
-
- if (pkchicken) {
- outc('\n');
- show_chicken_stat(pkchicken, age);
- outs("[任意鍵] 攻擊對方 [q] 落跑 [o] 吃大補丸");
- }
-}
-
-static void
-ch_eat(chicken_t *mychicken)
-{
- if (mychicken->food) {
- mychicken->weight += time_change[(int)mychicken->type][WEIGHT] +
- mychicken->hp_max / 5;
- mychicken->tiredstrong +=
- time_change[(int)mychicken->type][TIREDSTRONG] / 2;
- mychicken->hp_max++;
- mychicken->happy += 5;
- mychicken->satis += 7;
- mychicken->food--;
- move(10, 10);
-
- show_chicken_picture(CHICKEN_PIC "/eat");
- pressanykey();
- }
-}
-
-static void
-ch_clean(chicken_t *mychicken)
-{
- mychicken->clean = 0;
- mychicken->tiredstrong +=
- time_change[(int)mychicken->type][TIREDSTRONG] / 3;
- show_chicken_picture(CHICKEN_PIC "/clean");
- pressanykey();
-}
-
-static void
-ch_guess(chicken_t *mychicken)
-{
- char *guess[3] = {"剪刀", "石頭", "布"}, me, ch, win;
-
- mychicken->happy += time_change[(int)mychicken->type][HAPPY] * 1.5;
- mychicken->satis += time_change[(int)mychicken->type][SATIS];
- mychicken->tiredstrong += time_change[(int)mychicken->type][TIREDSTRONG];
- mychicken->attack += time_change[(int)mychicken->type][ATTACK] / 4;
- move(20, 0);
- clrtobot();
- outs("你要出[" ANSI_COLOR(32) "1" ANSI_RESET "]" ANSI_COLOR(33) "剪刀" ANSI_RESET "(" ANSI_COLOR(32) "2" ANSI_RESET ")"
- ANSI_COLOR(33) "石頭" ANSI_RESET "(" ANSI_COLOR(32) "3" ANSI_RESET ")" ANSI_COLOR(33) "布" ANSI_RESET ":\n");
- me = igetch();
- me -= '1';
- if (me > 2 || me < 0)
- me = 0;
- win = (int)(3.0 * random() / (RAND_MAX + 1.0)) - 1;
- ch = (me + win + 3) % 3;
- prints("%s:%s ! %s:%s !.....%s",
- cuser.userid, guess[(int)me], mychicken->name, guess[(int)ch],
- win == 0 ? "平手" : win < 0 ? "耶..贏了 :D!!" : "嗚..我輸了 :~");
- pressanykey();
-}
-
-static void
-ch_book(chicken_t *mychicken)
-{
- mychicken->book += time_change[(int)mychicken->type][BOOK];
- mychicken->tiredstrong += time_change[(int)mychicken->type][TIREDSTRONG];
- show_chicken_picture(CHICKEN_PIC "/read");
- pressanykey();
-}
-
-static void
-ch_kiss(chicken_t *mychicken)
-{
- mychicken->happy += time_change[(int)mychicken->type][HAPPY];
- mychicken->satis += time_change[(int)mychicken->type][SATIS];
- mychicken->tiredstrong +=
- time_change[(int)mychicken->type][TIREDSTRONG] / 2;
- show_chicken_picture(CHICKEN_PIC "/kiss");
- pressanykey();
-}
-
-static void
-ch_hit(chicken_t *mychicken)
-{
- mychicken->attack += time_change[(int)mychicken->type][ATTACK];
- mychicken->run += time_change[(int)mychicken->type][RUN];
- mychicken->mm_max += time_change[(int)mychicken->type][MM_MAX] / 15;
- mychicken->weight -= mychicken->hp_max / 15;
- mychicken->hp -= (int)((float)time_change[(int)mychicken->type][HP_MAX] *
- random() / (RAND_MAX + 1.0)) / 2 + 1;
-
- if (mychicken->book > 2)
- mychicken->book -= 2;
- if (mychicken->happy > 2)
- mychicken->happy -= 2;
- if (mychicken->satis > 2)
- mychicken->satis -= 2;
- mychicken->tiredstrong += time_change[(int)mychicken->type][TIREDSTRONG];
- show_chicken_picture(CHICKEN_PIC "/hit");
- pressanykey();
-}
-
-void
-ch_buyitem(int money, const char *picture, int *item, int haveticket)
-{
- int num = 0;
- char buf[5];
-
- getdata_str(b_lines - 1, 0, "要買多少份呢:",
- buf, sizeof(buf), DOECHO, "1");
- num = atoi(buf);
- if (num < 1)
- return;
- reload_money();
- if (cuser.money/money >= num) {
- *item += num;
- if( haveticket )
- vice(money * num, "購買寵物,賭盤項目");
- else
- demoney(-money * num);
- show_chicken_picture(picture);
- pressanykey();
- } else {
- vmsg("現金不夠 !!!");
- }
- usleep(100000); // sleep 0.1s
-}
-
-static void
-ch_eatoo(chicken_t *mychicken)
-{
- if (mychicken->oo > 0) {
- mychicken->oo--;
- mychicken->tiredstrong = 0;
- if (mychicken->happy > 5)
- mychicken->happy -= 5;
- show_chicken_picture(CHICKEN_PIC "/oo");
- pressanykey();
- }
-}
-
-static void
-ch_eatmedicine(chicken_t *mychicken)
-{
- if (mychicken->medicine > 0) {
- mychicken->medicine--;
- mychicken->sick = 0;
- if (mychicken->hp_max > 10)
- mychicken->hp_max -= 3;
- mychicken->hp = mychicken->hp_max;
- if (mychicken->happy > 10)
- mychicken->happy -= 10;
- show_chicken_picture(CHICKEN_PIC "/medicine");
- pressanykey();
- }
-}
-
-static void
-ch_kill(chicken_t *mychicken)
-{
- int ans;
-
- ans = getans("棄養要被罰 100 元, 是否要棄養?(y/N)");
- if (ans == 'y') {
-
- vice(100, "棄養寵物費");
- more(CHICKEN_PIC "/deadth", YEA);
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s " ANSI_RESET "把 " ANSI_COLOR(33) "%s" ANSI_RESET ANSI_COLOR(32) " %s "
- ANSI_RESET "宰了 於 %s\n", cuser.userid, mychicken->name,
- chicken_type[(int)mychicken->type], ctime4(&now));
- mychicken->name[0] = 0;
- }
-}
-
-static void
-geting_old(int *hp, int *weight, int diff, int age)
-{
- float ex = 0.9;
-
- if (age > 70)
- ex = 0.1;
- else if (age > 30)
- ex = 0.5;
- else if (age > 20)
- ex = 0.7;
-
- diff /= 60 * 6;
- while (diff--) {
- *hp *= ex;
- *weight *= ex;
- }
-}
-
-/* 依時間變動的資料 */
-static void
-time_diff(chicken_t * thechicken)
-{
- int diff;
- int theage = ((now - thechicken->cbirth) / (60 * 60 * 24));
-
- thechicken->type %= NUM_KINDS;
- diff = (now - thechicken->lastvisit) / 60;
-
- if ((diff) < 1)
- return;
-
- if (theage > 13) /* 老死 */
- geting_old(&thechicken->hp_max, &thechicken->weight, diff, theage);
-
- thechicken->lastvisit = now;
- thechicken->weight -= thechicken->hp_max * diff / 540; /* 體重 */
- if (thechicken->weight < 1) {
- thechicken->sick -= thechicken->weight / 10; /* 餓得病氣上升 */
- thechicken->weight = 1;
- }
- /* 清潔度 */
- thechicken->clean += diff * time_change[(int)thechicken->type][CLEAN] / 30;
-
- /* 快樂度 */
- thechicken->happy -= diff / 60;
- if (thechicken->happy < 0)
- thechicken->happy = 0;
- thechicken->attack -=
- time_change[(int)thechicken->type][ATTACK] * diff / (60 * 32);
- if (thechicken->attack < 0)
- thechicken->attack = 0;
- /* 攻擊力 */
- thechicken->run -= time_change[(int)thechicken->type][RUN] * diff / (60 * 32);
- /* 敏捷 */
- if (thechicken->run < 0)
- thechicken->run = 0;
- thechicken->book -= time_change[(int)thechicken->type][BOOK] * diff / (60 * 32);
- /* 知識 */
- if (thechicken->book < 0)
- thechicken->book = 0;
- /* 氣質 */
- thechicken->temperament++;
-
- thechicken->satis -= diff / 60 / 3 * time_change[(int)thechicken->type][SATIS];
- /* 滿意度 */
- if (thechicken->satis < 0)
- thechicken->satis = 0;
-
- /* 髒病的 */
- if (thechicken->clean > 1000)
- thechicken->sick += (thechicken->clean - 400) / 10;
-
- if (thechicken->weight > 1)
- thechicken->sick -= diff / 60;
- /* 病氣恢護 */
- if (thechicken->sick < 0)
- thechicken->sick = 0;
- thechicken->tiredstrong -= diff *
- time_change[(int)thechicken->type][TIREDSTRONG] / 4;
- /* 疲勞 */
- if (thechicken->tiredstrong < 0)
- thechicken->tiredstrong = 0;
- /* hp_max */
- if (thechicken->hp >= thechicken->hp_max / 2)
- thechicken->hp_max +=
- time_change[(int)thechicken->type][HP_MAX] * diff / (60 * 12);
- /* hp恢護 */
- if (!thechicken->sick)
- thechicken->hp +=
- time_change[(int)thechicken->type][HP_MAX] * diff / (60 * 6);
- if (thechicken->hp > thechicken->hp_max)
- thechicken->hp = thechicken->hp_max;
- /* mm_max */
- if (thechicken->mm >= thechicken->mm_max / 2)
- thechicken->mm_max +=
- time_change[(int)thechicken->type][MM_MAX] * diff / (60 * 8);
- /* mm恢護 */
- if (!thechicken->sick)
- thechicken->mm += diff;
- if (thechicken->mm > thechicken->mm_max)
- thechicken->mm = thechicken->mm_max;
-}
-
-static void
-check_sick(chicken_t *mychicken)
-{
- /* 髒病的 */
- if (mychicken->tiredstrong > mychicken->hp * 0.3 && mychicken->clean > 150)
- mychicken->sick += (mychicken->clean - 150) / 10;
- /* 累病的 */
- if (mychicken->tiredstrong > mychicken->hp * 1.3)
- mychicken->sick += time_change[(int)mychicken->type][SICK];
- /* 病氣太重還做事減hp */
- if (mychicken->sick > mychicken->hp / 5) {
- mychicken->hp -= (mychicken->sick - mychicken->hp / 5) / 4;
- if (mychicken->hp < 0)
- mychicken->hp = 0;
- }
-}
-
-static int
-deadtype(const chicken_t * thechicken, chicken_t *mychicken)
-{
- int i;
-
- if (thechicken->hp <= 0) /* hp用盡 */
- i = 1;
- else if (thechicken->tiredstrong > thechicken->hp * 3) /* 操勞過度 */
- i = 2;
- else if (thechicken->weight > thechicken->hp_max * 5) /* 肥胖過度 */
- i = 3;
- else if (thechicken->weight == 1 &&
- thechicken->sick > thechicken->hp_max / 4)
- i = 4; /* 餓死了 */
- else if (thechicken->satis <= 0) /* 很不滿意 */
- i = 5;
- else
- return 0;
-
- if (thechicken == mychicken) {
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s" ANSI_RESET " 所疼愛的" ANSI_COLOR(33) " %s" ANSI_COLOR(32) " %s "
- ANSI_RESET "掛了 於 %s\n", cuser.userid, thechicken->name,
- chicken_type[(int)thechicken->type], ctime4(&now));
- mychicken->name[0] = 0;
- }
- return i;
-}
-
-int
-showdeadth(int type)
-{
- switch (type) {
- case 1:
- more(CHICKEN_PIC "/nohp", YEA);
- break;
- case 2:
- more(CHICKEN_PIC "/tootired", YEA);
- break;
- case 3:
- more(CHICKEN_PIC "/toofat", YEA);
- break;
- case 4:
- more(CHICKEN_PIC "/nofood", YEA);
- break;
- case 5:
- more(CHICKEN_PIC "/nosatis", YEA);
- break;
- default:
- return 0;
- }
- more(CHICKEN_PIC "/deadth", YEA);
- return type;
-}
-
-static int
-isdeadth(const chicken_t * thechicken, chicken_t *mychicken)
-{
- int i;
-
- if (!(i = deadtype(thechicken, mychicken)))
- return 0;
- return showdeadth(i);
-}
-
-static void
-ch_changename(chicken_t *mychicken)
-{
- char newname[20] = "";
-
- getdata_str(b_lines - 1, 0, "嗯..改個好名字吧:", newname, 18, DOECHO,
- mychicken->name);
-
- if (strlen(newname) >= 3 && strcmp(newname, mychicken->name)) {
- strlcpy(mychicken->name, newname, sizeof(mychicken->name));
- log_filef(CHICKENLOG, LOG_CREAT,
- ANSI_COLOR(31) "%s" ANSI_RESET " 把疼愛的" ANSI_COLOR(33) " %s" ANSI_COLOR(32) " %s "
- ANSI_RESET "改名為" ANSI_COLOR(33) " %s" ANSI_RESET " 於 %s\n",
- cuser.userid, mychicken->name,
- chicken_type[(int)mychicken->type], newname, ctime4(&now));
- }
-}
-
-static int
-select_menu(int age, chicken_t *mychicken)
-{
- char ch;
-
- reload_money();
- move(19, 0);
- prints(ANSI_COLOR(44;37) " 錢 :" ANSI_COLOR(33) " %-10d "
- " " ANSI_RESET "\n"
- ANSI_COLOR(33) "(" ANSI_COLOR(37) "1" ANSI_COLOR(33) ")清理 (" ANSI_COLOR(37) "2" ANSI_COLOR(33) ")吃飯 "
- "(" ANSI_COLOR(37) "3" ANSI_COLOR(33) ")猜拳 (" ANSI_COLOR(37) "4" ANSI_COLOR(33) ")唸書 "
- "(" ANSI_COLOR(37) "5" ANSI_COLOR(33) ")親他 (" ANSI_COLOR(37) "6" ANSI_COLOR(33) ")打他 "
- "(" ANSI_COLOR(37) "7" ANSI_COLOR(33) ")買%s$%d (" ANSI_COLOR(37) "8" ANSI_COLOR(33) ")吃補丸\n"
- "(" ANSI_COLOR(37) "9" ANSI_COLOR(33) ")吃病藥 (" ANSI_COLOR(37) "o" ANSI_COLOR(33) ")買大補丸$100 "
- "(" ANSI_COLOR(37) "m" ANSI_COLOR(33) ")買藥$10 (" ANSI_COLOR(37) "k" ANSI_COLOR(33) ")棄養 "
- "(" ANSI_COLOR(37) "n" ANSI_COLOR(33) ")改名 "
- "(" ANSI_COLOR(37) "q" ANSI_COLOR(33) ")離開:" ANSI_RESET,
- cuser.money,
- /*
- * chicken_food[(int)mychicken->type],
- * chicken_type[(int)mychicken->type],
- * chicken_type[(int)mychicken->type],
- */
- chicken_food[(int)mychicken->type],
- food_price[(int)mychicken->type]);
- do {
- switch (ch = igetch()) {
- case '1':
- ch_clean(mychicken);
- check_sick(mychicken);
- break;
- case '2':
- ch_eat(mychicken);
- check_sick(mychicken);
- break;
- case '3':
- ch_guess(mychicken);
- check_sick(mychicken);
- break;
- case '4':
- ch_book(mychicken);
- check_sick(mychicken);
- break;
- case '5':
- ch_kiss(mychicken);
- break;
- case '6':
- ch_hit(mychicken);
- check_sick(mychicken);
- break;
- case '7':
- ch_buyitem(food_price[(int)mychicken->type], CHICKEN_PIC "/food",
- &mychicken->food, 1);
- break;
- case '8':
- ch_eatoo(mychicken);
- break;
- case '9':
- ch_eatmedicine(mychicken);
- break;
- case 'O':
- case 'o':
- ch_buyitem(100, CHICKEN_PIC "/buyoo", &mychicken->oo, 1);
- break;
- case 'M':
- case 'm':
- ch_buyitem(10, CHICKEN_PIC "/buymedicine", &mychicken->medicine, 1);
- break;
- case 'N':
- case 'n':
- ch_changename(mychicken);
- break;
- case 'K':
- case 'k':
- ch_kill(mychicken);
- return 0;
- case 'Q':
- case 'q':
- return 0;
- }
- } while (ch < ' ' || ch > 'z');
- return 1;
-}
-
-static int
-recover_chicken(chicken_t * thechicken)
-{
- char buf[200];
- int price = egg_price[(int)thechicken->type];
- int money = price + (random() % price);
- price *= 2;
- // money is a little less than price.
-
- if (now - thechicken->lastvisit > (60 * 60 * 24 * 7))
- return 0;
- outmsg(ANSI_COLOR(33;44) "★靈界守衛" ANSI_COLOR(37;45) " 別害怕 我是來幫你的 " ANSI_RESET);
- bell();
- igetch();
- outmsg(ANSI_COLOR(33;44) "★靈界守衛" ANSI_COLOR(37;45) " 你無法丟到我水球 因為我是聖靈, "
- "最近缺錢想賺外快 " ANSI_RESET);
- bell();
- igetch();
- snprintf(buf, sizeof(buf), ANSI_COLOR(33;44) "★靈界守衛" ANSI_COLOR(37;45) " "
- "你有一個剛走不久的%s要招換回來嗎? 只要 %d 元唷 " ANSI_RESET,
- chicken_type[(int)thechicken->type], price);
- outmsg(buf);
- bell();
- getdata_str(21, 0, " 選擇:(N:坑人嘛/y:請幫幫我)", buf, 3, LCECHO, "N");
- if (buf[0] == 'y' || buf[0] == 'Y') {
- reload_money();
- if (cuser.money < price) {
- outmsg(ANSI_COLOR(33;44) "★靈界守衛" ANSI_COLOR(37;45) " 什麼 錢沒帶夠 "
- "沒錢的小鬼 快去籌錢吧 " ANSI_RESET);
- bell();
- igetch();
- return 0;
- }
- strlcpy(thechicken->name, "[撿回來的]", sizeof(thechicken->name));
- thechicken->hp = thechicken->hp_max;
- thechicken->sick = 0;
- thechicken->satis = 2;
- thechicken->tiredstrong = 0;
- thechicken->weight = thechicken->hp;
- // thechicken->lastvisit = now; // really need so?
- vice(money, "靈界守衛");
- snprintf(buf, sizeof(buf),
- ANSI_COLOR(33;44) "★靈界守衛" ANSI_COLOR(37;45)
- " OK了 記得餵他點東西 不然可能失效。"
- "今天心情好,拿你$%d就好 " ANSI_RESET, money);
- outmsg(buf);
- bell();
- igetch();
- return 1;
- }
- outmsg(ANSI_COLOR(33;44) "★靈界守衛" ANSI_COLOR(37;45)
- " 竟然說我坑人! 這年頭命真不值錢 "
- "除非我再來找你 你再也沒機會了 " ANSI_RESET);
- bell();
- igetch();
- thechicken->lastvisit = 0;
- return 0;
-}
-
-void
-chicken_toggle_death(const char *uid)
-{
- chicken_t *mychicken = load_live_chicken(uid);
-
-#ifdef CHICKEN_LIVE_UPGRADE
- // live update
- vmsg("PTT 系統進行更新,本週暫停開放寵物設定。");
- return;
-#endif
-
- if (!uid)
- return;
- if (!mychicken)
- {
- vmsgf("%s 沒養寵物。", uid);
- }
- else if (mychicken->name[0])
- {
- mychicken->name[0] = 0;
- vmsgf("%s 的寵物被殺死了", uid);
- }
- else
- {
- strlcpy(mychicken->name, "[死]", sizeof(mychicken->name));
- vmsgf("%s 的寵物復活了", uid);
- }
- free_live_chicken(mychicken);
-}
-
-#define lockreturn0(unmode, state) if(lockutmpmode(unmode, state)) return 0
-
-#ifdef CHICKEN_LIVE_UPGRADE
-static void
-chicken_live_upgrade()
-{
- char fn[PATHLEN];
- FILE *fp = NULL;
- setuserfile(fn, FN_CHICKEN);
-
- if (dashf(fn))
- return;
-
- if (!cuser.old_chicken.name[0] &&
- !cuser.old_chicken.cbirth &&
- !cuser.old_chicken.hp_max)
- return;
-
- // write to data.
- fp = fopen(fn, "wb");
- fwrite(&cuser.old_chicken, sizeof(chicken_t), 1, fp);
- fclose(fp);
-#if 0 // enable if you want logs
- log_filef("log/chicken_live_upgrade", LOG_CREAT,
- "%s upgrade chicken at %s",
- cuser.userid, ctime4(&now));
-#endif
-}
-#endif // CHICKEN_LIVE_UPGRADE
-
-int
-chicken_main(void)
-{
- int age;
- chicken_t *mychicken = load_live_chicken(cuser.userid);
-
-#ifdef CHICKEN_LIVE_UPGRADE
- if (mychicken == NULL)
- {
- chicken_live_upgrade();
- mychicken = load_live_chicken(cuser.userid);
- }
-#endif
-
- lockreturn0(CHICKEN, LOCK_MULTI);
- if (mychicken && !mychicken->name[0])
- {
- // possible for recovery
- recover_chicken(mychicken);
- }
- if (!mychicken || !mychicken->name[0])
- {
- free_live_chicken(mychicken);
- mychicken = NULL;
-
- // create new?
- if (new_chicken())
- mychicken = load_live_chicken(cuser.userid);
-
- // exit if still no valid data.
- if (!mychicken || !mychicken->name[0])
- {
- unlockutmpmode();
- free_live_chicken(mychicken);
- return 0;
- }
- }
- assert(mychicken);
- age = ((now - mychicken->cbirth) / (60 * 60 * 24));
- do {
- time_diff(mychicken);
- if (isdeadth(mychicken, mychicken))
- break;
- show_chicken_data(mychicken, NULL);
- } while (select_menu(age, mychicken));
- unlockutmpmode();
- free_live_chicken(mychicken);
- return 0;
-}
-
-#ifdef USE_CHICKEN_PK
-int
-chickenpk(int fd)
-{
- chicken_t *mychicken = load_live_chicken(cuser.userid);
- chicken_t *ochicken = load_live_chicken(currutmp->mateid);
-
- char mateid[IDLEN + 1], data[200], buf[200];
- int ch = 0;
-
- userinfo_t *uin = &SHM->uinfo[currutmp->destuip];
- int r, attmax, i, datac, catched = 0,
- count = 0;
-
- lockreturn0(CHICKEN, LOCK_MULTI);
- /* 把對手的id用local buffer記住 */
- strlcpy(mateid, currutmp->mateid, sizeof(mateid));
-
- if (!mychicken || !ochicken ||
- !ochicken->name[0] || !mychicken->name[0]) {
- free_live_chicken(mychicken);
- free_live_chicken(ochicken);
- bell();
- vmsg("有一方沒有寵物"); /* Ptt:妨止page時把寵物賣掉 */
- add_io(0, 0);
- close(fd);
- unlockutmpmode();
- return 0;
- }
-
- show_chicken_data(ochicken, mychicken);
- add_io(fd, 3); /* 把fd加到igetch監視 */
-
- while (1) {
- r = random();
- ch = igetch();
- show_chicken_data(ochicken, mychicken);
- time_diff(mychicken);
-
- i = mychicken->attack * mychicken->hp / mychicken->hp_max;
- for (attmax = 2; (i = i * 9 / 10); attmax++);
-
- if (ch == I_OTHERDATA) {
- count = 0;
- datac = recv(fd, data, sizeof(data), 0);
- if (datac <= 1)
- break;
- move(17, 0);
- outs(data + 1);
- switch (data[0]) {
- case 'c':
- catched = 1;
- move(16, 0);
- outs("要放他走嗎?(y/N)");
- break;
- case 'd':
- move(16, 0);
- outs("阿~倒下了!!");
- break;
- }
- if (data[0] == 'd' || data[0] == 'q' || data[0] == 'l')
- break;
- continue;
- } else if (currutmp->turn) {
- count = 0;
- currutmp->turn = 0;
- uin->turn = 1;
- mychicken->tiredstrong++;
- switch (ch) {
- case 'y':
- if (catched == 1) {
- snprintf(data, sizeof(data),
- "l讓 %s 落跑了\n", ochicken->name);
- }
- break;
- case 'n':
- catched = 0;
- default:
- case 'k':
- r = r % (attmax + 2);
- if (r) {
- snprintf(data, sizeof(data),
- "M%s %s%s %s 傷了 %d 點\n", mychicken->name,
- damage_degree[r / 3 > 15 ? 15 : r / 3],
- attack_type[(int)mychicken->type],
- ochicken->name, r);
- ochicken->hp -= r;
- } else
- snprintf(data, sizeof(data),
- "M%s 覺得手軟出擊無效\n", mychicken->name);
- break;
- case 'o':
- if (mychicken->oo > 0) {
- mychicken->oo--;
- mychicken->hp += 300;
- if (mychicken->hp > mychicken->hp_max)
- mychicken->hp = mychicken->hp_max;
- mychicken->tiredstrong = 0;
- snprintf(data, sizeof(data), "M%s 吃了顆大補丸補充體力\n",
- mychicken->name);
- } else
- snprintf(data, sizeof(data),
- "M%s 想吃大補丸, 可是沒有大補丸可吃\n",
- mychicken->name);
- break;
- case 'q':
- if (r % (mychicken->run + 1) > r % (ochicken->run + 1))
- snprintf(data, sizeof(data), "q%s 落跑了\n",
- mychicken->name);
- else
- snprintf(data, sizeof(data),
- "c%s 想落跑, 但被 %s 抓到了\n",
- mychicken->name, ochicken->name);
- break;
- }
- if (deadtype(ochicken, mychicken)) {
- char *p = strchr(data, '\n');
- if(p) *p = '\0';
- strlcpy(buf, data, sizeof(buf));
- snprintf(data, sizeof(data), "d%s , %s 被 %s 打死了\n",
- buf + 1, ochicken->name, mychicken->name);
- }
- move(17, 0);
- outs(data + 1);
- i = strlen(data) + 1;
- send(fd, data, i, 0);
- if (data[0] == 'q' || data[0] == 'd')
- break;
- } else {
- move(17, 0);
- if (count++ > 30)
- break;
- }
- }
- add_io(0, 0); /* 把igetch恢復回 */
- pressanykey();
- close(fd);
- showdeadth(deadtype(mychicken, mychicken));
- unlockutmpmode();
- free_live_chicken(mychicken);
- free_live_chicken(ochicken);
- return 0;
-}
-#endif // USE_CHICKEN_PK