Crossfire Server, Trunk
armour_improver.cpp
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 
28 #include <global.h>
29 #include <ob_methods.h>
30 #include <ob_types.h>
31 #include <sounds.h>
32 #include <sproto.h>
33 
34 static method_ret armour_improver_type_apply(object *lighter, object *applier, int aflags);
35 
41 }
42 
59 static void improve_armour(object *op, object *improver, object *armour) {
60  object *tmp;
61  int oldmagic = armour->magic;
62 
63  if (armour->magic >= settings.armor_max_enchant) {
65  "This armour can not be enchanted any further.");
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  return;
78  }
79 
80  /* Check item power: if player has it equipped, unequip if armor
81  * would become unwearable. */
82  if (QUERY_FLAG(armour, FLAG_APPLIED)
83  && op->type == PLAYER
84  && (op->contr->item_power+1) > (settings.item_power_factor*op->level)) {
85  apply_special(op, armour, AP_UNAPPLY);
86  if (QUERY_FLAG(armour, FLAG_APPLIED)) {
87  /* Armour is cursed, too bad */
90  "You can't enchant this armour without unapplying it because it would consume your soul!");
91  return;
92  }
93  }
94 
95  /* Split objects if needed. Can't insert tmp until the
96  * end of this function - otherwise it will just re-merge. */
97  if (armour->nrof > 1)
98  tmp = object_split(armour, armour->nrof-1, NULL, 0);
99  else
100  tmp = NULL;
101 
102  armour->magic++;
103 
104  // set_abs_magic handles the weight and speed reductions, and the settings.
105  // It is also used for when item +X is spawned, but it will work fine here.
106  // There is one caveat -- if the armor was corroded and then this occurs,
107  // the weight may actually increase; haven't tested but I believe it to be
108  // the case. -- Neila Hawkins 2021-01-19
109  set_abs_magic(armour, armour->magic);
110 
111  if (armour->weight <= 0) {
112  LOG(llevInfo, "Warning: enchanted armours can have negative weight\n.");
113  armour->weight = 1;
114  }
115 
116  armour->item_power += (armour->magic-oldmagic)*3;
117  if (armour->item_power < 0)
118  armour->item_power = 0;
119 
120  if (op->type == PLAYER) {
122  if (QUERY_FLAG(armour, FLAG_APPLIED))
123  fix_object(op);
124  }
125  object_decrease_nrof_by_one(improver);
126  if (tmp) {
128  }
129  return;
130 }
131 
144 static method_ret armour_improver_type_apply(object *scroll, object *applier, int aflags) {
145  object *armor;
146  (void)aflags;
147 
148  if (applier->type != PLAYER)
149  return METHOD_UNHANDLED;
150 
151  if (!QUERY_FLAG(applier, FLAG_WIZCAST)
152  && (get_map_flags(applier->map, NULL, applier->x, applier->y, NULL, NULL)&P_NO_MAGIC)) {
154  "Something blocks the magic of the scroll.");
155  return METHOD_OK;
156  }
157  armor = find_marked_object(applier);
158  if (!armor) {
160  "You need to mark an armor object.");
161  return METHOD_OK;
162  }
163  if (armor->type != ARMOUR
164  && armor->type != CLOAK
165  && armor->type != BOOTS
166  && armor->type != GLOVES
167  && armor->type != BRACERS
168  && armor->type != SHIELD
169  && armor->type != HELMET) {
171  "Your marked item is not armour!");
172  return METHOD_OK;
173  }
174 
176  "Applying armour enchantment.");
177  improve_armour(applier, scroll, armor);
178  return METHOD_OK;
179 }
PLAYER
@ PLAYER
Definition: object.h:112
global.h
settings
struct Settings settings
Definition: init.cpp:139
set_abs_magic
void set_abs_magic(object *op, int magic)
Definition: treasure.cpp:618
BRACERS
@ BRACERS
Definition: object.h:222
ARMOUR_IMPROVER
@ ARMOUR_IMPROVER
Definition: object.h:237
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:58
GLOVES
@ GLOVES
Definition: object.h:218
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
object::item_power
int8_t item_power
Definition: object.h:372
UPD_WEIGHT
#define UPD_WEIGHT
Definition: newclient.h:305
register_apply
void register_apply(int ob_type, apply_func method)
Definition: ob_types.cpp:62
METHOD_OK
#define METHOD_OK
Definition: ob_methods.h:15
object::x
int16_t x
Definition: object.h:335
ARMOUR
@ ARMOUR
Definition: object.h:125
object::map
struct mapstruct * map
Definition: object.h:305
FLAG_WIZCAST
#define FLAG_WIZCAST
Definition: define.h:289
fix_object
void fix_object(object *op)
Definition: living.cpp:1125
Ice.tmp
int tmp
Definition: Ice.py:207
init_type_armour_improver
void init_type_armour_improver(void)
Definition: armour_improver.cpp:39
P_NO_MAGIC
#define P_NO_MAGIC
Definition: map.h:225
UPD_NROF
#define UPD_NROF
Definition: newclient.h:310
object::title
sstring title
Definition: object.h:325
FLAG_APPLIED
#define FLAG_APPLIED
Definition: define.h:235
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.cpp:2853
METHOD_UNHANDLED
#define METHOD_UNHANDLED
Definition: ob_methods.h:16
object::y
int16_t y
Definition: object.h:335
CLOAK
@ CLOAK
Definition: object.h:209
HELMET
@ HELMET
Definition: object.h:141
object_decrease_nrof_by_one
#define object_decrease_nrof_by_one(xyz)
Definition: compat.h:32
MSG_TYPE_APPLY_SUCCESS
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:592
object::type
uint8_t type
Definition: object.h:348
object::magic
int8_t magic
Definition: object.h:358
Settings::item_power_factor
float item_power_factor
Definition: global.h:303
improve_armour
static void improve_armour(object *op, object *improver, object *armour)
Definition: armour_improver.cpp:59
sproto.h
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
object::weight
int32_t weight
Definition: object.h:375
method_ret
char method_ret
Definition: ob_methods.h:14
ob_types.h
sounds.h
llevInfo
@ llevInfo
Definition: logger.h:12
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:251
get_map_flags
int get_map_flags(mapstruct *oldmap, mapstruct **newmap, int16_t x, int16_t y, int16_t *nx, int16_t *ny)
Definition: map.cpp:300
give.op
op
Definition: give.py:33
object_split
object * object_split(object *orig_ob, uint32_t nr, char *err, size_t size)
Definition: object.cpp:2633
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Definition: main.cpp:359
apply_special
int apply_special(object *who, object *op, int aflags)
Definition: apply.cpp:1156
Settings::armor_max_enchant
int armor_max_enchant
Definition: global.h:305
UPD_NAME
#define UPD_NAME
Definition: newclient.h:307
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.cpp:308
armour_improver_type_apply
static method_ret armour_improver_type_apply(object *lighter, object *applier, int aflags)
Definition: armour_improver.cpp:144
object::nrof
uint32_t nrof
Definition: object.h:342
ob_methods.h
AP_UNAPPLY
#define AP_UNAPPLY
Definition: define.h:575
BOOTS
@ BOOTS
Definition: object.h:217
SHIELD
@ SHIELD
Definition: object.h:140
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Definition: newclient.h:397
MSG_TYPE_APPLY_ERROR
#define MSG_TYPE_APPLY_ERROR
Definition: newclient.h:590
find_marked_object
object * find_marked_object(object *op)
Definition: c_object.cpp:1520