Atrinik Server 2.5
types/food.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00031 #include <global.h>
00032 #include <math.h>
00033 
00035 #define FOOD_MAX 999
00036 
00041 void apply_food(object *op, object *tmp)
00042 {
00043     if (op->type != PLAYER)
00044     {
00045         op->stats.hp = op->stats.maxhp;
00046     }
00047     else
00048     {
00049         char buf[MAX_BUF];
00050 
00051         if (op->stats.food + tmp->stats.food > FOOD_MAX)
00052         {
00053             if ((op->stats.food + tmp->stats.food) - FOOD_MAX > tmp->stats.food / 5)
00054             {
00055                 new_draw_info(0, COLOR_WHITE, op, "You are too full to eat this right now!");
00056                 return;
00057             }
00058 
00059             if (tmp->type == FOOD || tmp->type == FLESH)
00060             {
00061                 new_draw_info(0, COLOR_WHITE, op, "You feel full, but what a waste of food!");
00062             }
00063             else
00064             {
00065                 new_draw_info(0, COLOR_WHITE, op, "Most of the drink goes down your face not your throat!");
00066             }
00067         }
00068 
00069         if (!QUERY_FLAG(tmp, FLAG_CURSED) && !QUERY_FLAG(tmp, FLAG_DAMNED))
00070         {
00071             int capacity_remaining = FOOD_MAX - op->stats.food;
00072 
00073             if (tmp->type == DRINK)
00074             {
00075                 snprintf(buf, sizeof(buf), "Ahhh... that %s tasted good.", tmp->name);
00076             }
00077             else
00078             {
00079                 snprintf(buf, sizeof(buf), "The %s tasted %s", tmp->name, tmp->type == FLESH ? "terrible!" : "good.");
00080             }
00081 
00082             op->stats.food += tmp->stats.food;
00083             CONTR(op)->stat_food_consumed += tmp->stats.food;
00084 
00085             if (capacity_remaining < tmp->stats.food)
00086             {
00087                 op->stats.hp += capacity_remaining / 50;
00088             }
00089             else
00090             {
00091                 op->stats.hp += tmp->stats.food / 50;
00092             }
00093 
00094             if (op->stats.hp > op->stats.maxhp)
00095             {
00096                 op->stats.hp = op->stats.maxhp;
00097             }
00098         }
00099         /* cursed/damned = food is decreased instead of increased */
00100         else
00101         {
00102             int ft = tmp->stats.food;
00103 
00104             snprintf(buf, sizeof(buf), "The %s tasted terrible!", tmp->name);
00105 
00106             if (ft > 0)
00107             {
00108                 ft = -ft;
00109             }
00110 
00111             op->stats.food += ft;
00112         }
00113 
00114         CONTR(op)->stat_food_num_consumed++;
00115 
00116         new_draw_info(0, COLOR_WHITE, op, buf);
00117 
00118         /* adjust food to borders when needed */
00119         if (op->stats.food > FOOD_MAX)
00120         {
00121             op->stats.food = FOOD_MAX;
00122         }
00123         else if (op->stats.food < 0)
00124         {
00125             op->stats.food = 0;
00126         }
00127 
00128         /* special food hack -b.t. */
00129         if (tmp->title || QUERY_FLAG(tmp, FLAG_CURSED)|| QUERY_FLAG(tmp, FLAG_DAMNED))
00130         {
00131             eat_special_food(op, tmp);
00132         }
00133     }
00134 
00135     decrease_ob(tmp);
00136 }
00137 
00144 void create_food_force(object* who, object *food, object *force)
00145 {
00146     int i;
00147 
00148     force->stats.Str = food->stats.Str;
00149     force->stats.Pow = food->stats.Pow;
00150     force->stats.Dex = food->stats.Dex;
00151     force->stats.Con = food->stats.Con;
00152     force->stats.Int = food->stats.Int;
00153     force->stats.Wis = food->stats.Wis;
00154     force->stats.Cha = food->stats.Cha;
00155 
00156     for (i = 0; i < NROFATTACKS; i++)
00157     {
00158         force->protection[i] = food->protection[i];
00159     }
00160 
00161     /* if damned, set all negative if not and double or triple them */
00162     if (QUERY_FLAG(food, FLAG_CURSED) || QUERY_FLAG(food, FLAG_DAMNED))
00163     {
00164         int stat_multiplier = QUERY_FLAG(food, FLAG_CURSED) ? 2 : 3;
00165 
00166         if (force->stats.Str > 0)
00167         {
00168             force->stats.Str =- force->stats.Str;
00169         }
00170 
00171         force->stats.Str *= stat_multiplier;
00172 
00173         if (force->stats.Dex > 0)
00174         {
00175             force->stats.Dex =- force->stats.Dex;
00176         }
00177 
00178         force->stats.Dex *= stat_multiplier;
00179 
00180         if (force->stats.Con > 0)
00181         {
00182             force->stats.Con =- force->stats.Con;
00183         }
00184 
00185         force->stats.Con *= stat_multiplier;
00186 
00187         if (force->stats.Int > 0)
00188         {
00189             force->stats.Int =- force->stats.Int;
00190         }
00191 
00192         force->stats.Int *= stat_multiplier;
00193 
00194         if (force->stats.Wis > 0)
00195         {
00196             force->stats.Wis =- force->stats.Wis;
00197         }
00198 
00199         force->stats.Wis *= stat_multiplier;
00200 
00201         if (force->stats.Pow > 0)
00202         {
00203             force->stats.Pow =- force->stats.Pow;
00204         }
00205 
00206         force->stats.Pow *= stat_multiplier;
00207 
00208         if (force->stats.Cha > 0)
00209         {
00210             force->stats.Cha =- force->stats.Cha;
00211         }
00212 
00213         force->stats.Cha *= stat_multiplier;
00214 
00215         for (i = 0; i < NROFATTACKS; i++)
00216         {
00217             if (force->protection[i] > 0)
00218             {
00219                 force->protection[i] =- force->protection[i];
00220             }
00221 
00222             force->protection[i] *= stat_multiplier;
00223         }
00224     }
00225 
00226     if (food->speed_left)
00227     {
00228         force->speed = food->speed_left;
00229     }
00230 
00231     SET_FLAG(force, FLAG_APPLIED);
00232 
00233     force = insert_ob_in_ob(force, who);
00234     /* Mostly to display any messages */
00235     change_abil(who, force);
00236     /* This takes care of some stuff that change_abil() */
00237     fix_player(who);
00238 }
00239 
00259 void eat_special_food(object *who, object *food)
00260 {
00261     /* if there is any stat or protection value - create force for the object! */
00262     if (food->stats.Pow || food->stats.Str || food->stats.Dex || food->stats.Con || food->stats.Int || food->stats.Wis || food->stats.Cha)
00263     {
00264         create_food_force(who, food, get_archetype("force"));
00265     }
00266     else
00267     {
00268         int i;
00269 
00270         for (i = 0; i < NROFATTACKS; i++)
00271         {
00272             if (food->protection[i] > 0)
00273             {
00274                 create_food_force(who, food, get_archetype("force"));
00275                 break;
00276             }
00277         }
00278     }
00279 
00280     /* Check for hp, sp and grace change */
00281     if (food->stats.hp)
00282     {
00283         if (QUERY_FLAG(food, FLAG_CURSED) || QUERY_FLAG(food, FLAG_DAMNED))
00284         {
00285             int tmp = food->stats.hp;
00286 
00287             if (tmp > 0)
00288             {
00289                 tmp = -tmp;
00290             }
00291 
00292             strcpy(CONTR(who)->killer, food->name);
00293 
00294             if (QUERY_FLAG(food, FLAG_CURSED))
00295             {
00296                 who->stats.hp += tmp * 2;
00297             }
00298             else
00299             {
00300                 who->stats.hp += tmp * 3;
00301             }
00302 
00303             new_draw_info(0, COLOR_WHITE, who, "Eck!... that was rotten food!");
00304         }
00305         else
00306         {
00307             new_draw_info(0, COLOR_WHITE, who, "You begin to feel better.");
00308             who->stats.hp += food->stats.hp;
00309 
00310             if (who->stats.hp > who->stats.maxhp)
00311             {
00312                 who->stats.hp = who->stats.maxhp;
00313             }
00314         }
00315     }
00316 
00317     if (food->stats.sp)
00318     {
00319         if (QUERY_FLAG(food, FLAG_CURSED) || QUERY_FLAG(food, FLAG_DAMNED))
00320         {
00321             int tmp = food->stats.sp;
00322 
00323             if (tmp > 0)
00324             {
00325                 tmp = -tmp;
00326             }
00327 
00328             new_draw_info(0, COLOR_WHITE, who, "Your mana is drained!");
00329 
00330             if (QUERY_FLAG(food, FLAG_CURSED))
00331             {
00332                 who->stats.sp += tmp * 2;
00333             }
00334             else
00335             {
00336                 who->stats.sp += tmp * 3;
00337             }
00338 
00339             if (who->stats.sp < 0)
00340             {
00341                 who->stats.sp = 0;
00342             }
00343         }
00344         else
00345         {
00346             new_draw_info(0, COLOR_WHITE, who, "You feel a rush of magical energy!");
00347             who->stats.sp += food->stats.sp;
00348 
00349             if (who->stats.sp > who->stats.maxsp)
00350             {
00351                 who->stats.sp = who->stats.maxsp;
00352             }
00353         }
00354     }
00355 
00356     if (food->stats.grace && determine_god(who) != shstr_cons.none)
00357     {
00358         if (QUERY_FLAG(food, FLAG_CURSED) || QUERY_FLAG(food, FLAG_DAMNED))
00359         {
00360             int tmp = food->stats.grace;
00361 
00362             if (tmp > 0)
00363             {
00364                 tmp = -tmp;
00365             }
00366 
00367             new_draw_info(0, COLOR_WHITE, who, "Your grace is drained!");
00368 
00369             if (QUERY_FLAG(food, FLAG_CURSED))
00370             {
00371                 who->stats.grace += tmp * 2;
00372             }
00373             else
00374             {
00375                 who->stats.grace += tmp * 3;
00376             }
00377 
00378             if (who->stats.grace < 0)
00379             {
00380                 who->stats.grace = 0;
00381             }
00382         }
00383         else
00384         {
00385             new_draw_info(0, COLOR_WHITE, who, "You are returned to a state of grace.");
00386             who->stats.grace += food->stats.grace;
00387 
00388             if (who->stats.grace > who->stats.maxgrace)
00389             {
00390                 who->stats.grace = who->stats.maxgrace;
00391             }
00392         }
00393     }
00394 }