00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include <global.h>
00027 #include <ob_methods.h>
00028 #include <ob_types.h>
00029 #include <sounds.h>
00030 #include <sproto.h>
00031
00032 static method_ret potion_type_apply(ob_methods *context, object *potion,
00033 object *applier, int aflags);
00034
00038 void init_type_potion(void) {
00039 register_apply(POTION, potion_type_apply);
00040 }
00041
00050 static method_ret potion_type_apply(ob_methods *context, object *potion,
00051 object *applier, int aflags) {
00052 int got_one = 0, i;
00053 object *force;
00054
00055 if (applier->type == PLAYER) {
00056 if (!QUERY_FLAG(potion, FLAG_IDENTIFIED))
00057 identify(potion);
00058 }
00059
00060 handle_apply_yield(potion);
00061
00062
00063 if (applier->type == PLAYER && (potion->attacktype&AT_DEPLETE)) {
00064 object *depl;
00065 archetype *at;
00066
00067 if (QUERY_FLAG(potion, FLAG_CURSED) || QUERY_FLAG(potion, FLAG_DAMNED)) {
00068 drain_stat(applier);
00069 fix_object(applier);
00070 decrease_ob(potion);
00071 return METHOD_OK;
00072 }
00073
00074 if ((at = find_archetype(ARCH_DEPLETION)) == NULL) {
00075 LOG(llevError, "Could not find archetype depletion\n");
00076 return METHOD_ERROR;
00077 }
00078
00079 depl = present_arch_in_ob(at, applier);
00080 if (depl != NULL
00081 && (potion->level != 0 && potion->level >= applier->level)) {
00082 for (i = 0; i < NUM_STATS; i++)
00083 if (get_attr_value(&depl->stats, i)) {
00084 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_ATTRIBUTE, MSG_TYPE_ATTRIBUTE_STAT_GAIN,
00085 restore_msg[i], NULL);
00086 }
00087 remove_ob(depl);
00088 free_object(depl);
00089 fix_object(applier);
00090 }
00091 else
00092 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
00093 "You potion had no effect.", NULL);
00094
00095 decrease_ob(potion);
00096 return METHOD_OK;
00097 }
00098
00099
00100 if (applier->type == PLAYER && potion->attacktype&AT_GODPOWER) {
00101 for (i = 1; i < MIN(11, applier->level); i++) {
00102 if (QUERY_FLAG(potion, FLAG_CURSED) || QUERY_FLAG(potion, FLAG_DAMNED)) {
00103 if (applier->contr->levhp[i] != 1) {
00104 applier->contr->levhp[i] = 1;
00105 break;
00106 }
00107 if (applier->contr->levsp[i] != 1) {
00108 applier->contr->levsp[i] = 1;
00109 break;
00110 }
00111 if (applier->contr->levgrace[i] != 1) {
00112 applier->contr->levgrace[i] = 1;
00113 break;
00114 }
00115 } else {
00116 if (applier->contr->levhp[i] < 9) {
00117 applier->contr->levhp[i] = 9;
00118 break;
00119 }
00120 if (applier->contr->levsp[i] < 6) {
00121 applier->contr->levsp[i] = 6;
00122 break;
00123 }
00124 if (applier->contr->levgrace[i] < 3) {
00125 applier->contr->levgrace[i] = 3;
00126 break;
00127 }
00128 }
00129 }
00130
00131 if (i < MIN(11, applier->level))
00132 got_one = 1;
00133 if (!QUERY_FLAG(potion, FLAG_CURSED) && !QUERY_FLAG(potion, FLAG_DAMNED)) {
00134 if (got_one) {
00135 fix_object(applier);
00136 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS,
00137 "The Gods smile upon you and remake you a little more in their image."
00138 "You feel a little more perfect.", NULL);
00139 } else
00140 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
00141 "The potion had no effect - you are already perfect", NULL);
00142 } else {
00143 if (got_one) {
00144 fix_object(applier);
00145 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_CURSED,
00146 "The Gods are angry and punish you.", NULL);
00147 } else
00148 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_CURSED,
00149 "You are fortunate that you are so pathetic.", NULL);
00150 }
00151 decrease_ob(potion);
00152 return METHOD_OK;
00153 }
00154
00155
00156
00157
00158
00159
00160
00161 if (potion->inv) {
00162 if (QUERY_FLAG(potion, FLAG_CURSED) || QUERY_FLAG(potion, FLAG_DAMNED)) {
00163 object *fball;
00164
00165 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_CURSED,
00166 "Yech! Your lungs are on fire!", NULL);
00167
00168 fball = create_archetype(EXPLODING_FIREBALL);
00169 fball->dam_modifier = random_roll(1, applier->level, applier, PREFER_LOW)/5+1;
00170 fball->stats.maxhp = random_roll(1, applier->level, applier, PREFER_LOW)/10+2;
00171 fball->x = applier->x;
00172 fball->y = applier->y;
00173 insert_ob_in_map(fball, applier->map, NULL, 0);
00174 } else
00175 cast_spell(applier, potion, applier->facing, potion->inv, NULL);
00176
00177 decrease_ob(potion);
00178
00179 if (!QUERY_FLAG(applier, FLAG_REMOVED))
00180 fix_object(applier);
00181 return METHOD_OK;
00182 }
00183
00184
00185 force = NULL;
00186 for (i = 0; i < NROFATTACKS; i++) {
00187 if (potion->resist[i]) {
00188 if (!force)
00189 force = create_archetype(FORCE_NAME);
00190 memcpy(force->resist, potion->resist, sizeof(potion->resist));
00191 force->type = POTION_EFFECT;
00192 break;
00193 }
00194 }
00195
00196 if (force) {
00197
00198 if (QUERY_FLAG(potion, FLAG_CURSED) || QUERY_FLAG(potion, FLAG_DAMNED)) {
00199 force->stats.food *= 10;
00200 for (i = 0; i < NROFATTACKS; i++)
00201 if (force->resist[i] > 0)
00202 force->resist[i] = -force->resist[i];
00203 }
00204 force->speed_left = -1;
00205 force = insert_ob_in_ob(force, applier);
00206 CLEAR_FLAG(potion, FLAG_APPLIED);
00207 SET_FLAG(force, FLAG_APPLIED);
00208 change_abil(applier, force);
00209 decrease_ob(potion);
00210 return METHOD_OK;
00211 }
00212
00213
00214 if (applier->type == PLAYER) {
00215 if ((QUERY_FLAG(potion, FLAG_CURSED) || QUERY_FLAG(potion, FLAG_DAMNED))
00216 && potion->value != 0)
00217 CLEAR_FLAG(potion, FLAG_APPLIED);
00218 else
00219 SET_FLAG(potion, FLAG_APPLIED);
00220 if (!change_abil(applier, potion))
00221 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
00222 "Nothing happened.", NULL);
00223 }
00224
00225
00226
00227
00228
00229
00230 CLEAR_FLAG(potion, FLAG_APPLIED);
00231 fix_object(applier);
00232 decrease_ob(potion);
00233 return METHOD_OK;
00234 }