Crossfire Server, Branches 1.12  R18729
armour_improver.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2007 Crossfire Development Team
5  Copyright (C) 1992 Frank Tore Johansen
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  The authors can be reached via e-mail at crossfire-devel@real-time.com
22 */
23 
27 #include <global.h>
28 #include <ob_methods.h>
29 #include <ob_types.h>
30 #include <sounds.h>
31 #include <sproto.h>
32 
33 static method_ret armour_improver_type_apply(ob_methods *context, object *lighter, object *applier, int aflags);
34 
40 }
41 
58 static void improve_armour(object *op, object *improver, object *armour) {
59  object *tmp;
60  int oldmagic = armour->magic;
61 
62  if (armour->magic >= settings.armor_max_enchant) {
64  "This armour can not be enchanted any further.",
65  NULL);
66  return;
67  }
68 
69  /* Dealing with random artifact armor is a lot trickier
70  * (in terms of value, weight, etc), so take the easy way out
71  * and don't worry about it. Note - maybe add scrolls which
72  * make the random artifact versions (eg, armour of gnarg and
73  * what not?) */
74  if (armour->title) {
76  "This armour will not accept further enchantment.",
77  NULL);
78  return;
79  }
80 
81  /* Check item power: if player has it equipped, unequip if armor
82  * would become unwearable. */
83  if (QUERY_FLAG(armour, FLAG_APPLIED)
84  && op->type == PLAYER
85  && (op->contr->item_power+1) > (settings.item_power_factor*op->level)) {
86  apply_special(op, armour, AP_UNAPPLY);
87  if (QUERY_FLAG(armour, FLAG_APPLIED)) {
88  /* Armour is cursed, too bad */
91  "You can't enchant this armour without unapplying it because it would consume your soul!", NULL);
92  return;
93  }
94  }
95 
96  /* Split objects if needed. Can't insert tmp until the
97  * end of this function - otherwise it will just re-merge. */
98  if (armour->nrof > 1)
99  tmp = get_split_ob(armour, armour->nrof-1, NULL, 0);
100  else
101  tmp = NULL;
102 
103  armour->magic++;
104 
106  int base = 100;
107  int pow = 0;
108 
109  while (pow < armour->magic) {
110  base = base-(base*settings.armor_speed_improvement)/100;
111  pow++;
112  }
113 
114  ARMOUR_SPEED(armour) = (ARMOUR_SPEED(&armour->arch->clone)*base)/100;
115  } else
116  ARMOUR_SPEED(armour) = (ARMOUR_SPEED(&armour->arch->clone)*(100+armour->magic*settings.armor_speed_improvement))/100;
117 
119  int base = 100;
120  int pow = 0;
121 
122  while (pow < armour->magic) {
123  base = base-(base*settings.armor_weight_reduction)/100;
124  pow++;
125  }
126  armour->weight = (armour->arch->clone.weight*base)/100;
127  } else
128  armour->weight = (armour->arch->clone.weight*(100-armour->magic*settings.armor_weight_reduction))/100;
129 
130  if (armour->weight <= 0) {
131  LOG(llevInfo, "Warning: enchanted armours can have negative weight\n.");
132  armour->weight = 1;
133  }
134 
135  armour->item_power += (armour->magic-oldmagic)*3;
136  if (armour->item_power < 0)
137  armour->item_power = 0;
138 
139  if (op->type == PLAYER) {
141  if (QUERY_FLAG(armour, FLAG_APPLIED))
142  fix_object(op);
143  }
144  decrease_ob(improver);
145  if (tmp) {
146  insert_ob_in_ob(tmp, op);
147  }
148  return;
149 }
150 
165 static method_ret armour_improver_type_apply(ob_methods *context, object *scroll, object *applier, int aflags) {
166  object *armor;
167 
168  if (applier->type != PLAYER)
169  return METHOD_UNHANDLED;
170 
171  if (!QUERY_FLAG(applier, FLAG_WIZCAST)
172  && (get_map_flags(applier->map, NULL, applier->x, applier->y, NULL, NULL)&P_NO_MAGIC)) {
174  "Something blocks the magic of the scroll.", NULL);
175  return METHOD_OK;
176  }
177  armor = find_marked_object(applier);
178  if (!armor) {
180  "You need to mark an armor object.", NULL);
181  return METHOD_OK;
182  }
183  if (armor->type != ARMOUR
184  && armor->type != CLOAK
185  && armor->type != BOOTS
186  && armor->type != GLOVES
187  && armor->type != BRACERS
188  && armor->type != SHIELD
189  && armor->type != HELMET) {
191  "Your marked item is not armour!", NULL);
192  return METHOD_OK;
193  }
194 
196  "Applying armour enchantment.", NULL);
197  improve_armour(applier, scroll, armor);
198  return METHOD_OK;
199 }
#define AP_UNAPPLY
Definition: define.h:1010
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, sint16 x, sint16 y, sint16 *nx, sint16 *ny)
Definition: map.c:330
int apply_special(object *who, object *op, int aflags)
Definition: apply.c:1139
#define UPD_NAME
Definition: newclient.h:258
#define P_NO_MAGIC
Definition: map.h:248
void esrv_update_item(int flags, object *pl, object *op)
Definition: standalone.c:200
object clone
Definition: object.h:326
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
int armor_max_enchant
Definition: global.h:394
#define BOOTS
Definition: define.h:281
#define CLOAK
Definition: define.h:268
sint16 x
Definition: object.h:179
#define ARMOUR
Definition: define.h:128
#define PLAYER
Definition: define.h:113
char method_ret
Definition: ob_methods.h:41
const char * title
Definition: object.h:170
static void improve_armour(object *op, object *improver, object *armour)
int armor_speed_improvement
Definition: global.h:397
sint32 weight
Definition: object.h:216
#define METHOD_OK
Definition: ob_methods.h:42
static method_ret armour_improver_type_apply(ob_methods *context, object *lighter, object *applier, int aflags)
sint16 item_power
Definition: player.h:171
struct mapdef * map
Definition: object.h:155
void init_type_armour_improver(void)
#define ARMOUR_SPEED(xyz)
Definition: define.h:788
uint32 nrof
Definition: object.h:184
sint16 y
Definition: object.h:179
void register_apply(int ob_type, apply_func method)
Definition: ob_types.c:79
struct pl * contr
Definition: object.h:134
sint8 item_power
Definition: object.h:213
#define UPD_NROF
Definition: newclient.h:261
object * find_marked_object(object *op)
Definition: c_object.c:1339
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define MSG_TYPE_APPLY
Definition: newclient.h:330
object * insert_ob_in_ob(object *op, object *where)
Definition: object.c:2510
#define METHOD_UNHANDLED
Definition: ob_methods.h:43
#define GLOVES
Definition: define.h:282
#define BRACERS
Definition: define.h:286
#define SHIELD
Definition: define.h:145
#define decrease_ob(xyz)
Definition: global.h:276
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:518
int armor_weight_reduction
Definition: global.h:395
uint8 armor_weight_linear
Definition: global.h:396
#define FLAG_WIZCAST
Definition: define.h:586
struct archt * arch
Definition: object.h:263
struct Settings settings
Definition: init.c:48
#define ARMOUR_IMPROVER
Definition: define.h:307
#define FLAG_APPLIED
Definition: define.h:531
#define MSG_TYPE_APPLY_ERROR
Definition: newclient.h:516
#define UPD_WEIGHT
Definition: newclient.h:256
#define NDI_UNIQUE
Definition: newclient.h:219
#define HELMET
Definition: define.h:146
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
object * get_split_ob(object *orig_ob, uint32 nr, char *err, size_t size)
Definition: object.c:2313
sint16 level
Definition: object.h:202
void fix_object(object *op)
Definition: living.c:900
sint8 magic
Definition: object.h:199
float item_power_factor
Definition: global.h:392
uint8 armor_speed_linear
Definition: global.h:398
uint8 type
Definition: object.h:189