Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 CrossFire, A Multiplayer game for X-windows 00003 00004 Copyright (C) 2007 Crossfire Development Team 00005 Copyright (C) 1992 Frank Tore Johansen 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 00021 The authors can be reached via e-mail at crossfire-devel@real-time.com 00022 */ 00023 00027 #include <global.h> 00028 #include <ob_methods.h> 00029 #include <ob_types.h> 00030 #include <sounds.h> 00031 #include <sproto.h> 00032 00033 static method_ret armour_improver_type_apply(ob_methods *context, object *lighter, object *applier, int aflags); 00034 00038 void init_type_armour_improver(void) { 00039 register_apply(ARMOUR_IMPROVER, armour_improver_type_apply); 00040 } 00041 00058 static void improve_armour(object *op, object *improver, object *armour) { 00059 object *tmp; 00060 int oldmagic = armour->magic; 00061 00062 if (armour->magic >= settings.armor_max_enchant) { 00063 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00064 "This armour can not be enchanted any further.", 00065 NULL); 00066 return; 00067 } 00068 00069 /* Dealing with random artifact armor is a lot trickier 00070 * (in terms of value, weight, etc), so take the easy way out 00071 * and don't worry about it. Note - maybe add scrolls which 00072 * make the random artifact versions (eg, armour of gnarg and 00073 * what not?) */ 00074 if (armour->title) { 00075 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00076 "This armour will not accept further enchantment.", 00077 NULL); 00078 return; 00079 } 00080 00081 /* Check item power: if player has it equipped, unequip if armor 00082 * would become unwearable. */ 00083 if (QUERY_FLAG(armour, FLAG_APPLIED) 00084 && op->type == PLAYER 00085 && (op->contr->item_power+1) > (settings.item_power_factor*op->level)) { 00086 apply_special(op, armour, AP_UNAPPLY); 00087 if (QUERY_FLAG(armour, FLAG_APPLIED)) { 00088 /* Armour is cursed, too bad */ 00089 draw_ext_info(NDI_UNIQUE, 0, op, 00090 MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00091 "You can't enchant this armour without unapplying it because it would consume your soul!", NULL); 00092 return; 00093 } 00094 } 00095 00096 /* Split objects if needed. Can't insert tmp until the 00097 * end of this function - otherwise it will just re-merge. */ 00098 if (armour->nrof > 1) 00099 tmp = get_split_ob(armour, armour->nrof-1, NULL, 0); 00100 else 00101 tmp = NULL; 00102 00103 armour->magic++; 00104 00105 if (!settings.armor_speed_linear) { 00106 int base = 100; 00107 int pow = 0; 00108 00109 while (pow < armour->magic) { 00110 base = base-(base*settings.armor_speed_improvement)/100; 00111 pow++; 00112 } 00113 00114 ARMOUR_SPEED(armour) = (ARMOUR_SPEED(&armour->arch->clone)*base)/100; 00115 } else 00116 ARMOUR_SPEED(armour) = (ARMOUR_SPEED(&armour->arch->clone)*(100+armour->magic*settings.armor_speed_improvement))/100; 00117 00118 if (!settings.armor_weight_linear) { 00119 int base = 100; 00120 int pow = 0; 00121 00122 while (pow < armour->magic) { 00123 base = base-(base*settings.armor_weight_reduction)/100; 00124 pow++; 00125 } 00126 armour->weight = (armour->arch->clone.weight*base)/100; 00127 } else 00128 armour->weight = (armour->arch->clone.weight*(100-armour->magic*settings.armor_weight_reduction))/100; 00129 00130 if (armour->weight <= 0) { 00131 LOG(llevInfo, "Warning: enchanted armours can have negative weight\n."); 00132 armour->weight = 1; 00133 } 00134 00135 armour->item_power += (armour->magic-oldmagic)*3; 00136 if (armour->item_power < 0) 00137 armour->item_power = 0; 00138 00139 if (op->type == PLAYER) { 00140 esrv_update_item(UPD_WEIGHT|UPD_NAME|UPD_NROF, op, armour); 00141 if (QUERY_FLAG(armour, FLAG_APPLIED)) 00142 fix_object(op); 00143 } 00144 decrease_ob(improver); 00145 if (tmp) { 00146 insert_ob_in_ob(tmp, op); 00147 } 00148 return; 00149 } 00150 00165 static method_ret armour_improver_type_apply(ob_methods *context, object *scroll, object *applier, int aflags) { 00166 object *armor; 00167 00168 if (applier->type != PLAYER) 00169 return METHOD_UNHANDLED; 00170 00171 if (!QUERY_FLAG(applier, FLAG_WIZCAST) 00172 && (get_map_flags(applier->map, NULL, applier->x, applier->y, NULL, NULL)&P_NO_MAGIC)) { 00173 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00174 "Something blocks the magic of the scroll.", NULL); 00175 return METHOD_OK; 00176 } 00177 armor = find_marked_object(applier); 00178 if (!armor) { 00179 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00180 "You need to mark an armor object.", NULL); 00181 return METHOD_OK; 00182 } 00183 if (armor->type != ARMOUR 00184 && armor->type != CLOAK 00185 && armor->type != BOOTS 00186 && armor->type != GLOVES 00187 && armor->type != BRACERS 00188 && armor->type != SHIELD 00189 && armor->type != HELMET) { 00190 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR, 00191 "Your marked item is not armour!", NULL); 00192 return METHOD_OK; 00193 } 00194 00195 draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS, 00196 "Applying armour enchantment.", NULL); 00197 improve_armour(applier, scroll, armor); 00198 return METHOD_OK; 00199 }