ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/skills.C
(Generate patch)

Comparing deliantra/server/server/skills.C (file contents):
Revision 1.2 by elmex, Mon Aug 14 15:18:45 2006 UTC vs.
Revision 1.11 by root, Sat Sep 16 22:24:13 2006 UTC

1/*
2 * static char *rcsid_skills_c =
3 * "$Id: skills.C,v 1.2 2006/08/14 15:18:45 elmex Exp $";
4 */
5/* 1/*
6 CrossFire, A Multiplayer game for X-windows 2 CrossFire, A Multiplayer game for X-windows
7 3
8 Copyright (C) 2003 Mark Wedel & Crossfire Development Team 4 Copyright (C) 2003 Mark Wedel & Crossfire Development Team
9 Copyright (C) 1992 Frank Tore Johansen 5 Copyright (C) 1992 Frank Tore Johansen
20 16
21 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software 18 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 20
25 The authors can be reached via e-mail to crossfire-devel@real-time.com 21 The authors can be reached via e-mail to <crossfire@schmorp.de>
26*/ 22*/
27 23
28#include <global.h> 24#include <global.h>
29#include <object.h> 25#include <object.h>
30#ifndef __CEXTRACT__ 26#ifndef __CEXTRACT__
31#include <sproto.h> 27# include <sproto.h>
32#endif 28#endif
33#include <living.h> 29#include <living.h>
34#include <skills.h> 30#include <skills.h>
35#include <spells.h> 31#include <spells.h>
36#include <book.h> 32#include <book.h>
37 33
38/* adj_stealchance() - increased values indicate better attempts */ 34/* adj_stealchance() - increased values indicate better attempts */
35static int
39static int adj_stealchance (object *op, object *victim, int roll) { 36adj_stealchance (object *op, object *victim, int roll)
37{
40 object *equip; 38 object *equip;
41 39
42 if(!op||!victim||!roll) return -1; 40 if (!op || !victim || !roll)
41 return -1;
43 42
44 /* Only prohibit stealing if the player does not have a free 43 /* Only prohibit stealing if the player does not have a free
45 * hand available and in fact does have hands. 44 * hand available and in fact does have hands.
46 */ 45 */
47 if(op->type==PLAYER && op->body_used[BODY_ARMS] <=0 && 46 if (op->type == PLAYER && op->body_used[BODY_ARMS] <= 0 && op->body_info[BODY_ARMS])
48 op->body_info[BODY_ARMS]) { 47 {
49 new_draw_info(NDI_UNIQUE, 0,op,"But you have no free hands to steal with!"); 48 new_draw_info (NDI_UNIQUE, 0, op, "But you have no free hands to steal with!");
50 return -1; 49 return -1;
51 } 50 }
52 51
53 /* ADJUSTMENTS */ 52 /* ADJUSTMENTS */
54 53
55 /* Its harder to steal from hostile beings! */ 54 /* Its harder to steal from hostile beings! */
56 if(!QUERY_FLAG(victim, FLAG_UNAGGRESSIVE)) roll = roll/2; 55 if (!QUERY_FLAG (victim, FLAG_UNAGGRESSIVE))
56 roll = roll / 2;
57 57
58 /* Easier to steal from sleeping beings, or if the thief is 58 /* Easier to steal from sleeping beings, or if the thief is
59 * unseen */ 59 * unseen */
60 if(QUERY_FLAG(victim, FLAG_SLEEP)) 60 if (QUERY_FLAG (victim, FLAG_SLEEP))
61 roll = roll*3; 61 roll = roll * 3;
62 else if(op->invisible) 62 else if (op->invisible)
63 roll = roll*2; 63 roll = roll * 2;
64 64
65 /* check stealing 'encumberance'. Having this equipment applied makes 65 /* check stealing 'encumberance'. Having this equipment applied makes
66 * it quite a bit harder to steal. 66 * it quite a bit harder to steal.
67 */ 67 */
68 for(equip=op->inv;equip;equip=equip->below) { 68 for (equip = op->inv; equip; equip = equip->below)
69 {
69 if(equip->type==WEAPON&&QUERY_FLAG(equip,FLAG_APPLIED)) { 70 if (equip->type == WEAPON && QUERY_FLAG (equip, FLAG_APPLIED))
71 {
70 roll -= equip->weight/10000; 72 roll -= equip->weight / 10000;
71 } 73 }
72 if(equip->type==BOW&&QUERY_FLAG(equip,FLAG_APPLIED)) 74 if (equip->type == BOW && QUERY_FLAG (equip, FLAG_APPLIED))
73 roll -= equip->weight/5000; 75 roll -= equip->weight / 5000;
74 if(equip->type==SHIELD&&QUERY_FLAG(equip,FLAG_APPLIED)) { 76 if (equip->type == SHIELD && QUERY_FLAG (equip, FLAG_APPLIED))
77 {
75 roll -= equip->weight/2000; 78 roll -= equip->weight / 2000;
76 } 79 }
77 if(equip->type==ARMOUR&&QUERY_FLAG(equip,FLAG_APPLIED)) 80 if (equip->type == ARMOUR && QUERY_FLAG (equip, FLAG_APPLIED))
78 roll -= equip->weight/5000; 81 roll -= equip->weight / 5000;
79 if(equip->type==GLOVES&&QUERY_FLAG(equip,FLAG_APPLIED)) 82 if (equip->type == GLOVES && QUERY_FLAG (equip, FLAG_APPLIED))
80 roll -= equip->weight/100; 83 roll -= equip->weight / 100;
81 } 84 }
82 if(roll<0) roll=0; 85 if (roll < 0)
86 roll = 0;
83 return roll; 87 return roll;
84} 88}
85 89
86/* 90/*
87 * When stealing: dependent on the intelligence/wisdom of whom you're 91 * When stealing: dependent on the intelligence/wisdom of whom you're
88 * stealing from (op in attempt_steal), offset by your dexterity and 92 * stealing from (op in attempt_steal), offset by your dexterity and
91 * op is the target (person being pilfered) 95 * op is the target (person being pilfered)
92 * who is the person doing the stealing. 96 * who is the person doing the stealing.
93 * skill is the skill object (stealing). 97 * skill is the skill object (stealing).
94 */ 98 */
95 99
100static int
96static int attempt_steal(object* op, object* who, object *skill) 101attempt_steal (object *op, object *who, object *skill)
97{ 102{
98 object *success=NULL, *tmp=NULL, *next; 103 object *success = NULL, *tmp = NULL, *next;
99 int roll=0, chance=0, stats_value; 104 int roll = 0, chance = 0, stats_value;
100 rv_vector rv; 105 rv_vector rv;
101 106
102 stats_value = ((who->stats.Dex + who->stats.Int) * 3) / 2; 107 stats_value = ((who->stats.Dex + who->stats.Int) * 3) / 2;
103 108
104 /* if the victim is aware of a thief in the area (FLAG_NO_STEAL set on them) 109 /* if the victim is aware of a thief in the area (FLAG_NO_STEAL set on them)
105 * they will try to prevent stealing if they can. Only unseen theives will 110 * they will try to prevent stealing if they can. Only unseen theives will
106 * have much chance of success. 111 * have much chance of success.
107 */ 112 */
108 if(op->type!=PLAYER && QUERY_FLAG(op,FLAG_NO_STEAL)) { 113 if (op->type != PLAYER && QUERY_FLAG (op, FLAG_NO_STEAL))
114 {
109 if(can_detect_enemy(op,who,&rv)) { 115 if (can_detect_enemy (op, who, &rv))
116 {
110 npc_call_help(op); 117 npc_call_help (op);
111 CLEAR_FLAG(op, FLAG_UNAGGRESSIVE); 118 CLEAR_FLAG (op, FLAG_UNAGGRESSIVE);
112 new_draw_info(NDI_UNIQUE, 0,who,"Your attempt is prevented!"); 119 new_draw_info (NDI_UNIQUE, 0, who, "Your attempt is prevented!");
113 return 0; 120 return 0;
121 }
114 } else /* help npc to detect thief next time by raising its wisdom */ 122 else /* help npc to detect thief next time by raising its wisdom */
115 op->stats.Wis += (op->stats.Int/5)+1; 123 op->stats.Wis += (op->stats.Int / 5) + 1;
116 if (op->stats.Wis > MAX_STAT) op->stats.Wis = MAX_STAT; 124 if (op->stats.Wis > MAX_STAT)
125 op->stats.Wis = MAX_STAT;
117 } 126 }
118 if (op->type == PLAYER && QUERY_FLAG(op, FLAG_WIZ)) { 127 if (op->type == PLAYER && QUERY_FLAG (op, FLAG_WIZ))
128 {
119 new_draw_info(NDI_UNIQUE, 0, who, "You can't steal from the dungeon master!\n"); 129 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from the dungeon master!\n");
120 return 0; 130 return 0;
121 } 131 }
122#ifdef PROHIBIT_PLAYERKILL 132#ifdef PROHIBIT_PLAYERKILL
123 if(op->type == PLAYER && who->type == PLAYER && (who->contr->peaceful || op->contr->peaceful)) { 133 if (op->type == PLAYER && who->type == PLAYER && (who->contr->peaceful || op->contr->peaceful))
134 {
124 new_draw_info(NDI_UNIQUE, 0, who, "You can't steal from other players!\n"); 135 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n");
125 return 0; 136 return 0;
126 } 137 }
127#else 138#else
128 if(op->type == PLAYER && who->type == PLAYER && settings.no_player_stealing) { 139 if (op->type == PLAYER && who->type == PLAYER && settings.no_player_stealing)
140 {
129 new_draw_info(NDI_UNIQUE, 0, who, "You can't steal from other players!\n"); 141 new_draw_info (NDI_UNIQUE, 0, who, "You can't steal from other players!\n");
130 return 0; 142 return 0;
131 } 143 }
132#endif 144#endif
133 145
134 146
135 /* Ok then, go thru their inventory, stealing */ 147 /* Ok then, go thru their inventory, stealing */
136 for(tmp = op->inv; tmp != NULL; tmp = next) { 148 for (tmp = op->inv; tmp != NULL; tmp = next)
149 {
137 next = tmp->below; 150 next = tmp->below;
138 151
139 /* you can't steal worn items, starting items, wiz stuff, 152 /* you can't steal worn items, starting items, wiz stuff,
140 * innate abilities, or items w/o a type. Generally 153 * innate abilities, or items w/o a type. Generally
141 * speaking, the invisibility flag prevents experience or 154 * speaking, the invisibility flag prevents experience or
142 * abilities from being stolen since these types are currently 155 * abilities from being stolen since these types are currently
143 * always invisible objects. I was implicit here so as to prevent 156 * always invisible objects. I was implicit here so as to prevent
144 * future possible problems. -b.t. 157 * future possible problems. -b.t.
145 * Flesh items generated w/ fix_flesh_item should have FLAG_NO_STEAL 158 * Flesh items generated w/ fix_flesh_item should have FLAG_NO_STEAL
146 * already -b.t. 159 * already -b.t.
147 */ 160 */
148 161
149 if (QUERY_FLAG(tmp,FLAG_WAS_WIZ) || QUERY_FLAG(tmp, FLAG_APPLIED) 162 if (QUERY_FLAG (tmp, FLAG_WAS_WIZ) || QUERY_FLAG (tmp, FLAG_APPLIED)
150 || !(tmp->type) 163 || !(tmp->type)
151 || tmp->type == EXPERIENCE || tmp->type == SPELL 164 || tmp->type == EXPERIENCE || tmp->type == SPELL
152 || QUERY_FLAG(tmp,FLAG_STARTEQUIP) 165 || QUERY_FLAG (tmp, FLAG_STARTEQUIP) || QUERY_FLAG (tmp, FLAG_NO_STEAL) || tmp->invisible)
153 || QUERY_FLAG(tmp,FLAG_NO_STEAL) 166 continue;
154 || tmp->invisible ) continue;
155 167
156 /* Okay, try stealing this item. Dependent on dexterity of thief, 168 /* Okay, try stealing this item. Dependent on dexterity of thief,
157 * skill level, see the adj_stealroll fctn for more detail. 169 * skill level, see the adj_stealroll fctn for more detail.
158 */ 170 */
159 171
160 roll=die_roll(2, 100, who, PREFER_LOW)/2; /* weighted 1-100 */ 172 roll = die_roll (2, 100, who, PREFER_LOW) / 2; /* weighted 1-100 */
161 173
162 if((chance=adj_stealchance(who,op,(stats_value+skill->level * 10 - op->level * 3)))==-1) 174 if ((chance = adj_stealchance (who, op, (stats_value + skill->level * 10 - op->level * 3))) == -1)
163 return 0; 175 return 0;
164 else if (roll < chance ) { 176 else if (roll < chance)
165 tag_t tmp_count = tmp->count; 177 {
166
167 pick_up(who, tmp); 178 pick_up (who, tmp);
168 /* need to see if the player actually stole this item - 179 /* need to see if the player actually stole this item -
169 * if it is in the players inv, assume it is. This prevents 180 * if it is in the players inv, assume it is. This prevents
170 * abuses where the player can not carry the item, so just 181 * abuses where the player can not carry the item, so just
171 * keeps stealing it over and over. 182 * keeps stealing it over and over.
172 */ 183 */
173 if (was_destroyed(tmp, tmp_count) || tmp->env != op) { 184 if (tmp->destroyed () || tmp->env != op)
185 {
174 /* for players, play_sound: steals item */ 186 /* for players, play_sound: steals item */
175 success = tmp; 187 success = tmp;
176 CLEAR_FLAG(tmp, FLAG_INV_LOCKED); 188 CLEAR_FLAG (tmp, FLAG_INV_LOCKED);
177 189
178 /* Don't delete it from target player until we know 190 /* Don't delete it from target player until we know
179 * the thief has picked it up. can't just look at tmp->count, 191 * the thief has picked it up. can't just look at tmp->count,
180 * as it's possible that it got merged when picked up. 192 * as it's possible that it got merged when picked up.
181 */ 193 */
182 if (op->type == PLAYER) 194 if (op->type == PLAYER)
183 esrv_del_item(op->contr, tmp_count); 195 esrv_del_item (op->contr, tmp->count);
196 }
197 break;
198 }
199 } /* for loop looking for an item */
200
201 if (!tmp)
202 {
203 new_draw_info_format (NDI_UNIQUE, 0, who, "%s%s has nothing you can steal!", op->type == PLAYER ? "" : "The ", query_name (op));
204 return 0;
184 } 205 }
185 break;
186 }
187 } /* for loop looking for an item */
188 206
189 if (!tmp) {
190 new_draw_info_format(NDI_UNIQUE, 0, who, "%s%s has nothing you can steal!",
191 op->type == PLAYER ? "" : "The ", query_name(op));
192 return 0;
193 }
194
195 /* If you arent high enough level, you might get something BUT 207 /* If you arent high enough level, you might get something BUT
196 * the victim will notice your stealing attempt. Ditto if you 208 * the victim will notice your stealing attempt. Ditto if you
197 * attempt to steal something heavy off them, they're bound to notice 209 * attempt to steal something heavy off them, they're bound to notice
198 */ 210 */
199 211
200 if((roll>=skill->level) || !chance 212 if ((roll >= skill->level) || !chance
201 ||(tmp && tmp->weight>(250*(random_roll(0, stats_value+skill->level * 10-1, who, PREFER_LOW))))) { 213 || (tmp && tmp->weight > (250 * (random_roll (0, stats_value + skill->level * 10 - 1, who, PREFER_LOW)))))
214 {
202 215
203 /* victim figures out where the thief is! */ 216 /* victim figures out where the thief is! */
204 if(who->hide) make_visible(who); 217 if (who->hide)
218 make_visible (who);
205 219
206 if(op->type != PLAYER) { 220 if (op->type != PLAYER)
221 {
207 /* The unaggressives look after themselves 8) */ 222 /* The unaggressives look after themselves 8) */
208 if(who->type==PLAYER) { 223 if (who->type == PLAYER)
209 npc_call_help(op); 224 {
210 new_draw_info_format(NDI_UNIQUE, 0,who, 225 npc_call_help (op);
211 "%s notices your attempted pilfering!",query_name(op)); 226 new_draw_info_format (NDI_UNIQUE, 0, who, "%s notices your attempted pilfering!", query_name (op));
212 } 227 }
213 CLEAR_FLAG(op, FLAG_UNAGGRESSIVE); 228 CLEAR_FLAG (op, FLAG_UNAGGRESSIVE);
214 /* all remaining npc items are guarded now. Set flag NO_STEAL 229 /* all remaining npc items are guarded now. Set flag NO_STEAL
215 * on the victim. 230 * on the victim.
216 */ 231 */
217 SET_FLAG(op,FLAG_NO_STEAL); 232 SET_FLAG (op, FLAG_NO_STEAL);
218 } else { /* stealing from another player */ 233 }
234 else
235 { /* stealing from another player */
219 char buf[MAX_BUF]; 236 char buf[MAX_BUF];
237
220 /* Notify the other player */ 238 /* Notify the other player */
221 if (success && who->stats.Int > random_roll(0, 19, op, PREFER_LOW)) { 239 if (success && who->stats.Int > random_roll (0, 19, op, PREFER_LOW))
240 {
222 sprintf(buf, "Your %s is missing!", query_name(success)); 241 sprintf (buf, "Your %s is missing!", query_name (success));
223 } else { 242 }
243 else
244 {
224 sprintf(buf, "Your pack feels strangely lighter."); 245 sprintf (buf, "Your pack feels strangely lighter.");
225 } 246 }
226 new_draw_info(NDI_UNIQUE, 0,op,buf); 247 new_draw_info (NDI_UNIQUE, 0, op, buf);
227 if (!success) { 248 if (!success)
228 if (who->invisible) { 249 {
250 if (who->invisible)
251 {
229 sprintf(buf, "you feel itchy fingers getting at your pack."); 252 sprintf (buf, "you feel itchy fingers getting at your pack.");
230 } else { 253 }
254 else
255 {
231 sprintf(buf, "%s looks very shifty.", query_name(who)); 256 sprintf (buf, "%s looks very shifty.", query_name (who));
232 } 257 }
233 new_draw_info(NDI_UNIQUE, 0,op,buf); 258 new_draw_info (NDI_UNIQUE, 0, op, buf);
234 } 259 }
235 } /* else stealing from another player */ 260 } /* else stealing from another player */
236 /* play_sound("stop! thief!"); kindofthing */ 261 /* play_sound("stop! thief!"); kindofthing */
237 } /* if you weren't 100% successful */ 262 } /* if you weren't 100% successful */
238 return success? 1:0; 263 return success ? 1 : 0;
239} 264}
240 265
241 266
267int
242int steal(object* op, int dir, object *skill) 268steal (object *op, int dir, object *skill)
243{ 269{
244 object *tmp, *next; 270 object *tmp, *next;
245 sint16 x, y; 271 sint16 x, y;
246 mapstruct *m; 272 maptile *m;
247 int mflags; 273 int mflags;
248 274
249 x = op->x + freearr_x[dir]; 275 x = op->x + freearr_x[dir];
250 y = op->y + freearr_y[dir]; 276 y = op->y + freearr_y[dir];
277
278 if (dir == 0)
251 279 {
252 if(dir == 0) {
253 /* Can't steal from ourself! */ 280 /* Can't steal from ourself! */
254 return 0; 281 return 0;
255 } 282 }
256 283
257 m = op->map; 284 m = op->map;
258 mflags = get_map_flags(m, &m ,x,y, &x, &y); 285 mflags = get_map_flags (m, &m, x, y, &x, &y);
259 /* Out of map - can't do it. If nothing alive on this space, 286 /* Out of map - can't do it. If nothing alive on this space,
260 * don't need to look any further. 287 * don't need to look any further.
261 */ 288 */
262 if ((mflags & P_OUT_OF_MAP) || !(mflags & P_IS_ALIVE)) 289 if ((mflags & P_OUT_OF_MAP) || !(mflags & P_IS_ALIVE))
263 return 0;
264
265 /* If player can't move onto the space, can't steal from it. */
266 if (OB_TYPE_MOVE_BLOCK(op, GET_MAP_MOVE_BLOCK(m, x, y)))
267 return 0;
268
269 /* Find the topmost object at this spot */
270 for(tmp = get_map_ob(m,x,y);
271 tmp != NULL && tmp->above != NULL;
272 tmp = tmp->above);
273
274 /* For all the stacked objects at this point, attempt a steal */
275 for(; tmp != NULL; tmp = next) {
276 next = tmp->below;
277 /* Minor hack--for multi square beings - make sure we get
278 * the 'head' coz 'tail' objects have no inventory! - b.t.
279 */
280 if (tmp->head) tmp=tmp->head;
281
282 if(tmp->type!=PLAYER && !QUERY_FLAG(tmp, FLAG_MONSTER)) continue;
283
284 /* do not reveal hidden DMs */
285 if (tmp->type == PLAYER && QUERY_FLAG(tmp, FLAG_WIZ) && tmp->contr->hidden) continue;
286 if (attempt_steal(tmp, op, skill)) {
287 if (tmp->type==PLAYER) /* no xp for stealing from another player */
288 return 0;
289
290 /* no xp for stealing from pets (of players) */
291 if (QUERY_FLAG(tmp, FLAG_FRIENDLY) && tmp->attack_movement == PETMOVE) {
292 object *owner = get_owner(tmp);
293 if (owner != NULL && owner->type == PLAYER)
294 return 0;
295 }
296
297 // reduce monster experience by experience we gained, as to
298 // limit the amount of exp that can be gained by stealing from monsters
299 // (jessies gave ~20,000,000 exp otherwise.
300 int exp = calc_skill_exp (op, tmp, skill);
301 exp = MIN (tmp->stats.exp, exp);
302 tmp->stats.exp -= exp;
303 return exp;
304 }
305 }
306 return 0; 290 return 0;
307}
308 291
292 /* If player can't move onto the space, can't steal from it. */
293 if (OB_TYPE_MOVE_BLOCK (op, GET_MAP_MOVE_BLOCK (m, x, y)))
294 return 0;
295
296 /* Find the topmost object at this spot */
297 for (tmp = get_map_ob (m, x, y); tmp != NULL && tmp->above != NULL; tmp = tmp->above);
298
299 /* For all the stacked objects at this point, attempt a steal */
300 for (; tmp != NULL; tmp = next)
301 {
302 next = tmp->below;
303 /* Minor hack--for multi square beings - make sure we get
304 * the 'head' coz 'tail' objects have no inventory! - b.t.
305 */
306 if (tmp->head)
307 tmp = tmp->head;
308
309 if (tmp->type != PLAYER && !QUERY_FLAG (tmp, FLAG_MONSTER))
310 continue;
311
312 /* do not reveal hidden DMs */
313 if (tmp->type == PLAYER && QUERY_FLAG (tmp, FLAG_WIZ) && tmp->contr->hidden)
314 continue;
315 if (attempt_steal (tmp, op, skill))
316 {
317 if (tmp->type == PLAYER) /* no xp for stealing from another player */
318 return 0;
319
320 /* no xp for stealing from pets (of players) */
321 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && tmp->attack_movement == PETMOVE)
322 {
323 object *owner = get_owner (tmp);
324
325 if (owner != NULL && owner->type == PLAYER)
326 return 0;
327 }
328
329 // reduce monster experience by experience we gained, as to
330 // limit the amount of exp that can be gained by stealing from monsters
331 // (jessies gave ~20,000,000 exp otherwise.
332 int exp = calc_skill_exp (op, tmp, skill);
333
334 exp = MIN (tmp->stats.exp, exp);
335 tmp->stats.exp -= exp;
336 return exp;
337 }
338 }
339 return 0;
340}
341
342static int
309static int attempt_pick_lock (object *door, object *pl, object *skill) 343attempt_pick_lock (object *door, object *pl, object *skill)
310{ 344{
311 int difficulty= pl->map->difficulty ? pl->map->difficulty : 0; 345 int difficulty = pl->map->difficulty ? pl->map->difficulty : 0;
312 int success = 0, number; /* did we get anything? */ 346 int success = 0, number; /* did we get anything? */
313 347
314 348
315 /* Try to pick the lock on this item (doors only for now). 349 /* Try to pick the lock on this item (doors only for now).
316 * Dependent on dexterity/skill SK_level of the player and 350 * Dependent on dexterity/skill SK_level of the player and
317 * the map level difficulty. 351 * the map level difficulty.
318 */ 352 */
319 number = (die_roll(2, 40, pl, PREFER_LOW)-2)/2; 353 number = (die_roll (2, 40, pl, PREFER_LOW) - 2) / 2;
320 if (number < (pl->stats.Dex + skill->level - difficulty)) { 354 if (number < (pl->stats.Dex + skill->level - difficulty))
355 {
321 remove_door(door); 356 remove_door (door);
322 success = 1; 357 success = 1;
323 } else if (door->inv && (door->inv->type==RUNE || door->inv->type==TRAP)) { /* set off any traps? */
324 spring_trap(door->inv,pl);
325 } 358 }
359 else if (door->inv && (door->inv->type == RUNE || door->inv->type == TRAP))
360 { /* set off any traps? */
361 spring_trap (door->inv, pl);
362 }
326 return success; 363 return success;
327} 364}
328 365
329 366
330/* Implementation by bt. (thomas@astro.psu.edu) 367/* Implementation by bt. (thomas@astro.psu.edu)
331 * monster implementation 7-7-95 by bt. 368 * monster implementation 7-7-95 by bt.
332 */ 369 */
333 370
371int
334int pick_lock(object *pl, int dir, object *skill) 372pick_lock (object *pl, int dir, object *skill)
335{ 373{
336 object *tmp; 374 object *tmp;
337 int x = pl->x + freearr_x[dir]; 375 int x = pl->x + freearr_x[dir];
338 int y = pl->y + freearr_y[dir]; 376 int y = pl->y + freearr_y[dir];
339 377
378 if (!dir)
340 if(!dir) dir=pl->facing; 379 dir = pl->facing;
341 380
342 /* For all the stacked objects at this point find a door*/ 381 /* For all the stacked objects at this point find a door */
343 if (out_of_map(pl->map,x,y)) { 382 if (out_of_map (pl->map, x, y))
383 {
344 new_draw_info(NDI_UNIQUE, 0,pl,"There is no lock there."); 384 new_draw_info (NDI_UNIQUE, 0, pl, "There is no lock there.");
345 return 0; 385 return 0;
346 } 386 }
347 387
348 for(tmp=get_map_ob(pl->map,x,y); tmp; tmp=tmp->above) 388 for (tmp = get_map_ob (pl->map, x, y); tmp; tmp = tmp->above)
349 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR) break; 389 if (tmp->type == DOOR || tmp->type == LOCKED_DOOR)
390 break;
350 391
351 if (!tmp) { 392 if (!tmp)
393 {
352 new_draw_info(NDI_UNIQUE, 0,pl,"There is no lock there."); 394 new_draw_info (NDI_UNIQUE, 0, pl, "There is no lock there.");
353 return 0; 395 return 0;
354 } 396 }
355 if (tmp->type == LOCKED_DOOR) { 397 if (tmp->type == LOCKED_DOOR)
398 {
356 new_draw_info(NDI_UNIQUE, 0,pl, "You can't pick that lock!"); 399 new_draw_info (NDI_UNIQUE, 0, pl, "You can't pick that lock!");
357 return 0; 400 return 0;
358 } 401 }
359 402
360 if (!tmp->move_block) { 403 if (!tmp->move_block)
404 {
361 new_draw_info(NDI_UNIQUE, 0,pl,"The door has no lock!"); 405 new_draw_info (NDI_UNIQUE, 0, pl, "The door has no lock!");
362 return 0; 406 return 0;
363 } 407 }
364 408
365 if (attempt_pick_lock(tmp, pl, skill)) { 409 if (attempt_pick_lock (tmp, pl, skill))
410 {
366 new_draw_info(NDI_UNIQUE, 0,pl,"You pick the lock."); 411 new_draw_info (NDI_UNIQUE, 0, pl, "You pick the lock.");
367 return calc_skill_exp(pl,NULL, skill); 412 return calc_skill_exp (pl, NULL, skill);
368 } else { 413 }
414 else
415 {
369 new_draw_info(NDI_UNIQUE, 0,pl, "You fail to pick the lock."); 416 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to pick the lock.");
370 return 0; 417 return 0;
371 } 418 }
372} 419}
373 420
374 421
375/* HIDE CODE. The user becomes undetectable (not just 'invisible') for 422/* HIDE CODE. The user becomes undetectable (not just 'invisible') for
376 * a short while (success and duration dependant on player SK_level, 423 * a short while (success and duration dependant on player SK_level,
377 * dexterity, charisma, and map difficulty). 424 * dexterity, charisma, and map difficulty).
378 * Players have a good chance of becoming 'unhidden' if they move 425 * Players have a good chance of becoming 'unhidden' if they move
379 * and like invisiblity will be come visible if they attack 426 * and like invisiblity will be come visible if they attack
380 * Implemented by b.t. (thomas@astro.psu.edu) 427 * Implemented by b.t. (thomas@astro.psu.edu)
381 * July 7, 1995 - made hiding possible for monsters. -b.t. 428 * July 7, 1995 - made hiding possible for monsters. -b.t.
382 */ 429 */
383 430
431static int
384static int attempt_hide(object *op, object *skill) { 432attempt_hide (object *op, object *skill)
433{
385 int number,difficulty=op->map->difficulty; 434 int number, difficulty = op->map->difficulty;
386 int terrain = hideability(op); 435 int terrain = hideability (op);
387 436
388 if(terrain<-10) /* not enough cover here */ 437 if (terrain < -10) /* not enough cover here */
389 return 0;
390
391 /* Hiding success and duration dependant on skill level,
392 * op->stats.Dex, map difficulty and terrain.
393 */
394
395 number = (die_roll(2, 25, op, PREFER_LOW)-2)/2;
396 if(!stand_near_hostile(op) && (number < (op->stats.Dex + skill->level + terrain - difficulty))) {
397 op->invisible += 100; /* set the level of 'hiddeness' */
398 if(op->type==PLAYER)
399 op->contr->tmp_invis=1;
400 op->hide=1;
401 return 1;
402 }
403 return 0; 438 return 0;
439
440 /* Hiding success and duration dependant on skill level,
441 * op->stats.Dex, map difficulty and terrain.
442 */
443
444 number = (die_roll (2, 25, op, PREFER_LOW) - 2) / 2;
445 if (!stand_near_hostile (op) && (number < (op->stats.Dex + skill->level + terrain - difficulty)))
446 {
447 op->invisible += 100; /* set the level of 'hiddeness' */
448 if (op->type == PLAYER)
449 op->contr->tmp_invis = 1;
450 op->hide = 1;
451 return 1;
452 }
453 return 0;
404} 454}
405 455
406/* patched this to take terrain into consideration */ 456/* patched this to take terrain into consideration */
407 457int
408int hide(object *op, object *skill) { 458hide (object *op, object *skill)
459{
409 460
410 /* the preliminaries -- Can we really hide now? */ 461 /* the preliminaries -- Can we really hide now? */
411 /* this keeps monsters from using invisibilty spells and hiding */ 462 /* this keeps monsters from using invisibilty spells and hiding */
412 463
413 if (QUERY_FLAG(op, FLAG_MAKE_INVIS)) { 464 if (QUERY_FLAG (op, FLAG_MAKE_INVIS))
465 {
414 new_draw_info(NDI_UNIQUE, 0,op,"You don't need to hide while invisible!"); 466 new_draw_info (NDI_UNIQUE, 0, op, "You don't need to hide while invisible!");
415 return 0; 467 return 0;
468 }
416 } else if (!op->hide && op->invisible>0 && op->type == PLAYER) { 469 else if (!op->hide && op->invisible > 0 && op->type == PLAYER)
470 {
417 new_draw_info(NDI_UNIQUE, 0,op,"Your attempt to hide breaks the invisibility spell!"); 471 new_draw_info (NDI_UNIQUE, 0, op, "Your attempt to hide breaks the invisibility spell!");
418 make_visible(op); 472 make_visible (op);
419 } 473 }
420 474
421 if(op->invisible>(50*skill->level)) { 475 if (op->invisible > (50 * skill->level))
476 {
422 new_draw_info(NDI_UNIQUE,0,op,"You are as hidden as you can get."); 477 new_draw_info (NDI_UNIQUE, 0, op, "You are as hidden as you can get.");
423 return 0; 478 return 0;
424 } 479 }
425 480
426 if(attempt_hide(op, skill)) { 481 if (attempt_hide (op, skill))
482 {
427 new_draw_info(NDI_UNIQUE, 0,op,"You hide in the shadows."); 483 new_draw_info (NDI_UNIQUE, 0, op, "You hide in the shadows.");
428 update_object(op,UP_OBJ_FACE); 484 update_object (op, UP_OBJ_FACE);
429 return calc_skill_exp(op, NULL, skill); 485 return calc_skill_exp (op, NULL, skill);
430 } 486 }
431 new_draw_info(NDI_UNIQUE,0,op,"You fail to conceal yourself."); 487 new_draw_info (NDI_UNIQUE, 0, op, "You fail to conceal yourself.");
432 return 0; 488 return 0;
433} 489}
434 490
435 491
436/* stop_jump() - End of jump. Clear flags, restore the map, and 492/* stop_jump() - End of jump. Clear flags, restore the map, and
437 * freeze the jumper a while to simulate the exhaustion 493 * freeze the jumper a while to simulate the exhaustion
438 * of jumping. 494 * of jumping.
439 */ 495 */
496static void
440static void stop_jump(object *pl, int dist, int spaces) { 497stop_jump (object *pl, int dist, int spaces)
498{
441 fix_player(pl); 499 fix_player (pl);
442 insert_ob_in_map(pl,pl->map,pl,0); 500 insert_ob_in_map (pl, pl->map, pl, 0);
443} 501}
444 502
445 503
504static int
446static int attempt_jump (object *pl, int dir, int spaces, object *skill) { 505attempt_jump (object *pl, int dir, int spaces, object *skill)
506{
447 object *tmp; 507 object *tmp;
448 int i,exp=0,dx=freearr_x[dir],dy=freearr_y[dir], mflags; 508 int i, exp = 0, dx = freearr_x[dir], dy = freearr_y[dir], mflags;
449 sint16 x, y; 509 sint16 x, y;
450 mapstruct *m; 510 maptile *m;
451 511
452 /* Jump loop. Go through spaces opject wants to jump. Halt the 512 /* Jump loop. Go through spaces opject wants to jump. Halt the
453 * jump if a wall or creature is in the way. We set FLAG_FLYING 513 * jump if a wall or creature is in the way. We set FLAG_FLYING
454 * temporarily to allow player to aviod exits/archs that are not 514 * temporarily to allow player to aviod exits/archs that are not
455 * fly_on, fly_off. This will also prevent pickup of objects 515 * fly_on, fly_off. This will also prevent pickup of objects
456 * while jumping over them. 516 * while jumping over them.
457 */ 517 */
458 518
459 remove_ob(pl); 519 remove_ob (pl);
460 520
461 /* 521 /*
462 * I don't think this is actually needed - all the movement 522 * I don't think this is actually needed - all the movement
463 * code is handled in this function, and I don't see anyplace 523 * code is handled in this function, and I don't see anyplace
464 * that cares about the move_type being flying. 524 * that cares about the move_type being flying.
465 */ 525 */
466 pl->move_type |= MOVE_FLY_LOW; 526 pl->move_type |= MOVE_FLY_LOW;
467 527
468 for(i=0;i<=spaces;i++) { 528 for (i = 0; i <= spaces; i++)
529 {
469 x = pl->x + dx; 530 x = pl->x + dx;
470 y = pl->y + dy; 531 y = pl->y + dy;
471 m = pl->map; 532 m = pl->map;
472 533
473 mflags = get_map_flags(m, &m, x, y, &x, &y); 534 mflags = get_map_flags (m, &m, x, y, &x, &y);
474 535
475 if (mflags & P_OUT_OF_MAP) { 536 if (mflags & P_OUT_OF_MAP)
537 {
476 (void) stop_jump(pl,i,spaces); 538 (void) stop_jump (pl, i, spaces);
477 return 0; 539 return 0;
478 } 540 }
479 if (OB_TYPE_MOVE_BLOCK(pl, GET_MAP_MOVE_BLOCK(m, x, y))) { 541 if (OB_TYPE_MOVE_BLOCK (pl, GET_MAP_MOVE_BLOCK (m, x, y)))
542 {
480 new_draw_info(NDI_UNIQUE, 0,pl,"Your jump is blocked."); 543 new_draw_info (NDI_UNIQUE, 0, pl, "Your jump is blocked.");
481 stop_jump(pl,i,spaces); 544 stop_jump (pl, i, spaces);
482 return 0; 545 return 0;
483 } 546 }
484 547
485 for(tmp=get_map_ob(m, x, y); tmp;tmp=tmp->above) { 548 for (tmp = get_map_ob (m, x, y); tmp; tmp = tmp->above)
549 {
486 /* Jump into creature */ 550 /* Jump into creature */
487 if(QUERY_FLAG(tmp, FLAG_MONSTER) 551 if (QUERY_FLAG (tmp, FLAG_MONSTER) || (tmp->type == PLAYER && (!QUERY_FLAG (tmp, FLAG_WIZ) || !tmp->contr->hidden)))
488 || (tmp->type==PLAYER && (!QUERY_FLAG(tmp, FLAG_WIZ) || !tmp->contr->hidden))) { 552 {
489 new_draw_info_format(NDI_UNIQUE, 0,pl,"You jump into %s%s.", 553 new_draw_info_format (NDI_UNIQUE, 0, pl, "You jump into %s%s.", tmp->type == PLAYER ? "" : "the ", &tmp->name);
490 tmp->type == PLAYER ? "" : "the ", tmp->name); 554 if (tmp->type != PLAYER ||
491 if(tmp->type!=PLAYER ||
492 (pl->type==PLAYER && pl->contr->party==NULL) || 555 (pl->type == PLAYER && pl->contr->party == NULL) ||
493 (pl->type==PLAYER && tmp->type==PLAYER && 556 (pl->type == PLAYER && tmp->type == PLAYER && pl->contr->party != tmp->contr->party))
494 pl->contr->party!=tmp->contr->party))
495 exp = skill_attack(tmp,pl,pl->facing,"kicked", skill); /* pl makes an attack */ 557 exp = skill_attack (tmp, pl, pl->facing, "kicked", skill); /* pl makes an attack */
496 stop_jump(pl,i,spaces); 558 stop_jump (pl, i, spaces);
497 return exp; /* note that calc_skill_exp() is already called by skill_attack() */ 559 return exp; /* note that calc_skill_exp() is already called by skill_attack() */
498 } 560 }
499 /* If the space has fly on set (no matter what the space is), 561 /* If the space has fly on set (no matter what the space is),
500 * we should get the effects - after all, the player is 562 * we should get the effects - after all, the player is
501 * effectively flying. 563 * effectively flying.
502 */ 564 */
503 if (tmp->move_on & MOVE_FLY_LOW) { 565 if (tmp->move_on & MOVE_FLY_LOW)
504 pl->x = x; 566 {
505 pl->y = y; 567 pl->x = x;
506 pl->map = m; 568 pl->y = y;
507 if (pl->contr) 569 pl->map = m;
508 esrv_map_scroll(&pl->contr->socket, dx, dy); 570 stop_jump (pl, i, spaces);
509 stop_jump(pl,i,spaces);
510 return calc_skill_exp(pl,NULL, skill); 571 return calc_skill_exp (pl, NULL, skill);
572 }
573 }
574 pl->x = x;
575 pl->y = y;
576 pl->map = m;
511 } 577 }
512 }
513 pl->x = x;
514 pl->y = y;
515 pl->map = m;
516 if (pl->contr)
517 esrv_map_scroll(&pl->contr->socket, dx, dy);
518 }
519 stop_jump(pl,i,spaces); 578 stop_jump (pl, i, spaces);
520 return calc_skill_exp(pl,NULL, skill); 579 return calc_skill_exp (pl, NULL, skill);
521} 580}
522 581
523/* jump() - this is both a new type of movement for player/monsters and 582/* jump() - this is both a new type of movement for player/monsters and
524 * an attack as well. 583 * an attack as well.
525 * Perhaps we should allow more spaces based on level, eg, level 50 584 * Perhaps we should allow more spaces based on level, eg, level 50
526 * jumper can jump several spaces? 585 * jumper can jump several spaces?
527 */ 586 */
528 587
588int
529int jump(object *pl, int dir, object *skill) 589jump (object *pl, int dir, object *skill)
530{ 590{
531 int spaces=0,stats; 591 int spaces = 0, stats;
532 int str = pl->stats.Str; 592 int str = pl->stats.Str;
533 int dex = pl->stats.Dex; 593 int dex = pl->stats.Dex;
534 594
535 dex = dex ? dex : 15; 595 dex = dex ? dex : 15;
536 str = str ? str : 10; 596 str = str ? str : 10;
537 597
538 stats=str*str*str*dex * skill->level; 598 stats = str * str * str * dex * skill->level;
539 599
540 if(pl->carrying!=0) /* don't want div by zero !! */ 600 if (pl->carrying != 0) /* don't want div by zero !! */
541 spaces=(int) (stats/pl->carrying); 601 spaces = (int) (stats / pl->carrying);
542 else 602 else
543 spaces=2; /* pl has no objects - gets the far jump */ 603 spaces = 2; /* pl has no objects - gets the far jump */
544 604
545 if(spaces>2) 605 if (spaces > 2)
546 spaces = 2; 606 spaces = 2;
547 else if(spaces==0) { 607 else if (spaces == 0)
608 {
548 new_draw_info(NDI_UNIQUE, 0,pl,"You are carrying too much weight to jump."); 609 new_draw_info (NDI_UNIQUE, 0, pl, "You are carrying too much weight to jump.");
549 return 0; 610 return 0;
550 } 611 }
551 return attempt_jump(pl,dir,spaces, skill); 612 return attempt_jump (pl, dir, spaces, skill);
552} 613}
553 614
554 615
555/* skill_ident() - this code is supposed to allow players to identify 616/* skill_ident() - this code is supposed to allow players to identify
556 * classes of objects with the various "auto-ident" skills. Player must 617 * classes of objects with the various "auto-ident" skills. Player must
560 * more generalized. Right now, skill indices are embedded in this routine. 621 * more generalized. Right now, skill indices are embedded in this routine.
561 * Returns amount of experience gained (on successful ident). 622 * Returns amount of experience gained (on successful ident).
562 * - b.t. (thomas@astro.psu.edu) 623 * - b.t. (thomas@astro.psu.edu)
563 */ 624 */
564 625
626static int
565static int do_skill_detect_curse(object *pl, object *skill) { 627do_skill_detect_curse (object *pl, object *skill)
628{
566 object *tmp; 629 object *tmp;
567 int success=0; 630 int success = 0;
568 631
569 for(tmp=pl->inv;tmp;tmp=tmp->below) 632 for (tmp = pl->inv; tmp; tmp = tmp->below)
570 if (!tmp->invisible 633 if (!tmp->invisible
571 && !QUERY_FLAG(tmp,FLAG_IDENTIFIED) && !QUERY_FLAG(tmp,FLAG_KNOWN_CURSED) 634 && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)
572 && (QUERY_FLAG(tmp,FLAG_CURSED) || QUERY_FLAG(tmp,FLAG_DAMNED)) && 635 && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) && tmp->item_power < skill->level)
573 tmp->item_power < skill->level) { 636 {
574 SET_FLAG(tmp,FLAG_KNOWN_CURSED); 637 SET_FLAG (tmp, FLAG_KNOWN_CURSED);
575 esrv_update_item(UPD_FLAGS, pl, tmp); 638 esrv_update_item (UPD_FLAGS, pl, tmp);
576 success+= calc_skill_exp(pl,tmp, skill); 639 success += calc_skill_exp (pl, tmp, skill);
577 } 640 }
578 641
579 /* Check ground, too, but only objects the player could pick up */ 642 /* Check ground, too, but only objects the player could pick up */
580 for(tmp=get_map_ob(pl->map,pl->x,pl->y);tmp;tmp=tmp->above) 643 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
581 if (can_pick(pl, tmp) && 644 if (can_pick (pl, tmp) &&
582 !QUERY_FLAG(tmp,FLAG_IDENTIFIED) && 645 !QUERY_FLAG (tmp, FLAG_IDENTIFIED) &&
583 !QUERY_FLAG(tmp,FLAG_KNOWN_CURSED) 646 !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)
584 && (QUERY_FLAG(tmp,FLAG_CURSED) || QUERY_FLAG(tmp,FLAG_DAMNED)) && 647 && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED)) && tmp->item_power < skill->level)
585 tmp->item_power < skill->level) { 648 {
586 SET_FLAG(tmp,FLAG_KNOWN_CURSED); 649 SET_FLAG (tmp, FLAG_KNOWN_CURSED);
587 esrv_update_item(UPD_FLAGS, pl, tmp); 650 esrv_update_item (UPD_FLAGS, pl, tmp);
588 success+= calc_skill_exp(pl,tmp, skill); 651 success += calc_skill_exp (pl, tmp, skill);
589 } 652 }
590 653
591 return success; 654 return success;
592} 655}
593 656
657static int
594static int do_skill_detect_magic(object *pl, object *skill) { 658do_skill_detect_magic (object *pl, object *skill)
659{
595 object *tmp; 660 object *tmp;
596 int success=0; 661 int success = 0;
597 662
598 for(tmp=pl->inv;tmp;tmp=tmp->below) 663 for (tmp = pl->inv; tmp; tmp = tmp->below)
599 if(!tmp->invisible 664 if (!tmp->invisible
600 && !QUERY_FLAG(tmp,FLAG_IDENTIFIED) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) 665 && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL)
601 && (is_magical(tmp)) && tmp->item_power < skill->level) { 666 && (is_magical (tmp)) && tmp->item_power < skill->level)
667 {
602 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 668 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
603 esrv_update_item(UPD_FLAGS, pl, tmp); 669 esrv_update_item (UPD_FLAGS, pl, tmp);
604 success+=calc_skill_exp(pl,tmp, skill); 670 success += calc_skill_exp (pl, tmp, skill);
605 } 671 }
606 672
607 /* Check ground, too, but like above, only if the object can be picked up*/ 673 /* Check ground, too, but like above, only if the object can be picked up */
608 for(tmp=get_map_ob(pl->map,pl->x,pl->y);tmp;tmp=tmp->above) 674 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
609 if (can_pick(pl, tmp) && 675 if (can_pick (pl, tmp) &&
610 !QUERY_FLAG(tmp,FLAG_IDENTIFIED) && 676 !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL) && (is_magical (tmp)) && tmp->item_power < skill->level)
611 !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) 677 {
612 && (is_magical(tmp)) && tmp->item_power < skill->level) {
613 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 678 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
614 esrv_update_item(UPD_FLAGS, pl, tmp); 679 esrv_update_item (UPD_FLAGS, pl, tmp);
615 success+=calc_skill_exp(pl,tmp, skill); 680 success += calc_skill_exp (pl, tmp, skill);
616 } 681 }
617 682
618 return success; 683 return success;
619} 684}
620 685
621/* Helper function for do_skill_ident, so that we can loop 686/* Helper function for do_skill_ident, so that we can loop
622 * over inventory AND objects on the ground conveniently. 687 * over inventory AND objects on the ground conveniently.
623 */ 688 */
689int
624int do_skill_ident2(object *tmp,object *pl, int obj_class, object *skill) 690do_skill_ident2 (object *tmp, object *pl, int obj_class, object *skill)
625{ 691{
626 int success = 0, chance; 692 int success = 0, chance;
627 int skill_value = skill->level * pl->stats.Int ? pl->stats.Int : 10; 693 int skill_value = skill->level * pl->stats.Int ? pl->stats.Int : 10;
628 694
629 if (!QUERY_FLAG (tmp,FLAG_IDENTIFIED) && !QUERY_FLAG (tmp,FLAG_NO_SKILL_IDENT) 695 if (!QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_NO_SKILL_IDENT)
630 && need_identify (tmp) && !tmp->invisible && tmp->type == obj_class) 696 && need_identify (tmp) && !tmp->invisible && tmp->type == obj_class)
631 { 697 {
632 chance = die_roll(3, 10, pl, PREFER_LOW) - 3 698 chance = die_roll (3, 10, pl, PREFER_LOW) - 3 + rndm (0, (tmp->magic ? tmp->magic * 5 : 1) - 1);
633 + rndm (0, (tmp->magic ? tmp->magic * 5 : 1) - 1);
634 699
635 if (skill_value >= chance) 700 if (skill_value >= chance)
636 { 701 {
637 identify(tmp); 702 identify (tmp);
638 703
639 if (pl->type==PLAYER) 704 if (pl->type == PLAYER)
640 { 705 {
641 new_draw_info_format (NDI_UNIQUE, 0, pl, "You identify %s.", long_desc (tmp, pl)); 706 new_draw_info_format (NDI_UNIQUE, 0, pl, "You identify %s.", long_desc (tmp, pl));
642 707
643 if (tmp->msg) 708 if (tmp->msg)
644 { 709 {
645 new_draw_info(NDI_UNIQUE, 0,pl, "The item has a story:"); 710 new_draw_info (NDI_UNIQUE, 0, pl, "The item has a story:");
646 new_draw_info(NDI_UNIQUE, 0,pl, tmp->msg); 711 new_draw_info (NDI_UNIQUE, 0, pl, tmp->msg);
647 } 712 }
648 713
649 /* identify will take care of updating the item if it is in the players inventory. IF on map, do it here */ 714 /* identify will take care of updating the item if it is in the players inventory. IF on map, do it here */
650 if (tmp->map) 715 if (tmp->map)
651 esrv_send_item (pl, tmp); 716 esrv_send_item (pl, tmp);
652 } 717 }
653 success += calc_skill_exp(pl,tmp, skill); 718 success += calc_skill_exp (pl, tmp, skill);
654 } 719 }
655 else 720 else
656 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); 721 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT);
657 } 722 }
658 723
659 return success; 724 return success;
660} 725}
661 726
662/* do_skill_ident() - workhorse for skill_ident() -b.t. 727/* do_skill_ident() - workhorse for skill_ident() -b.t.
663 */ 728 */
729static int
664static int do_skill_ident(object *pl, int obj_class, object *skill) { 730do_skill_ident (object *pl, int obj_class, object *skill)
731{
665 object *tmp; 732 object *tmp;
666 int success=0; 733 int success = 0;
667 734
668 for(tmp=pl->inv;tmp;tmp=tmp->below) 735 for (tmp = pl->inv; tmp; tmp = tmp->below)
669 success+=do_skill_ident2(tmp,pl,obj_class, skill); 736 success += do_skill_ident2 (tmp, pl, obj_class, skill);
670 /* check the ground */ 737 /* check the ground */
671 738
672 for(tmp=get_map_ob(pl->map,pl->x,pl->y);tmp;tmp=tmp->above) 739 for (tmp = get_map_ob (pl->map, pl->x, pl->y); tmp; tmp = tmp->above)
673 success+=do_skill_ident2(tmp,pl,obj_class, skill); 740 success += do_skill_ident2 (tmp, pl, obj_class, skill);
674 741
675 return success; 742 return success;
676} 743}
677 744
745int
678int skill_ident(object *pl, object *skill) { 746skill_ident (object *pl, object *skill)
747{
679 int success=0; 748 int success = 0;
680 749
681 if(pl->type != PLAYER) return 0; /* only players will skill-identify */ 750 if (pl->type != PLAYER)
751 return 0; /* only players will skill-identify */
682 752
683 new_draw_info(NDI_UNIQUE, 0,pl,"You look at the objects nearby..."); 753 new_draw_info (NDI_UNIQUE, 0, pl, "You look at the objects nearby...");
684 754
685 switch (skill->subtype) { 755 switch (skill->subtype)
756 {
686 case SK_SMITHERY: 757 case SK_SMITHERY:
687 success += do_skill_ident(pl,WEAPON, skill) + do_skill_ident(pl,ARMOUR, skill) 758 success += do_skill_ident (pl, WEAPON, skill) + do_skill_ident (pl, ARMOUR, skill)
688 + do_skill_ident(pl,BRACERS,skill) + do_skill_ident(pl,CLOAK,skill) 759 + do_skill_ident (pl, BRACERS, skill) + do_skill_ident (pl, CLOAK, skill)
689 + do_skill_ident(pl,BOOTS,skill) + do_skill_ident(pl,SHIELD,skill) 760 + do_skill_ident (pl, BOOTS, skill) + do_skill_ident (pl, SHIELD, skill)
690 + do_skill_ident(pl,GIRDLE,skill) + do_skill_ident(pl,HELMET,skill) 761 + do_skill_ident (pl, GIRDLE, skill) + do_skill_ident (pl, HELMET, skill) + do_skill_ident (pl, GLOVES, skill);
691 + do_skill_ident(pl,GLOVES,skill); 762 break;
692 break;
693 763
694 case SK_BOWYER: 764 case SK_BOWYER:
695 success += do_skill_ident(pl,BOW,skill) + do_skill_ident(pl,ARROW,skill); 765 success += do_skill_ident (pl, BOW, skill) + do_skill_ident (pl, ARROW, skill);
696 break; 766 break;
697 767
698 case SK_ALCHEMY: 768 case SK_ALCHEMY:
699 success += do_skill_ident(pl,POTION,skill) + do_skill_ident(pl,POISON,skill) 769 success += do_skill_ident (pl, POTION, skill) + do_skill_ident (pl, POISON, skill)
700 + do_skill_ident(pl,CONTAINER,skill) 770 + do_skill_ident (pl, CONTAINER, skill) + do_skill_ident (pl, DRINK, skill) + do_skill_ident (pl, INORGANIC, skill);
701 + do_skill_ident(pl,DRINK,skill) + do_skill_ident(pl,INORGANIC,skill); 771 break;
702 break;
703 772
704 case SK_WOODSMAN: 773 case SK_WOODSMAN:
705 success += do_skill_ident(pl,FOOD,skill) + do_skill_ident(pl,DRINK,skill) 774 success += do_skill_ident (pl, FOOD, skill) + do_skill_ident (pl, DRINK, skill) + do_skill_ident (pl, FLESH, skill);
706 + do_skill_ident(pl,FLESH,skill); 775 break;
707 break;
708 776
709 case SK_JEWELER: 777 case SK_JEWELER:
710 success += do_skill_ident(pl,GEM,skill) + do_skill_ident(pl,RING,skill) + 778 success += do_skill_ident (pl, GEM, skill) + do_skill_ident (pl, RING, skill) + do_skill_ident (pl, AMULET, skill);
711 do_skill_ident(pl,AMULET,skill); 779 break;
712 break;
713 780
714 case SK_LITERACY: 781 case SK_LITERACY:
715 success += do_skill_ident(pl,SPELLBOOK,skill) 782 success += do_skill_ident (pl, SPELLBOOK, skill) + do_skill_ident (pl, SCROLL, skill) + do_skill_ident (pl, BOOK, skill);
716 + do_skill_ident(pl,SCROLL,skill) + do_skill_ident(pl,BOOK,skill); 783 break;
717 break;
718 784
719 case SK_THAUMATURGY: 785 case SK_THAUMATURGY:
720 success += do_skill_ident(pl,WAND,skill) + do_skill_ident(pl,ROD,skill) 786 success += do_skill_ident (pl, WAND, skill) + do_skill_ident (pl, ROD, skill) + do_skill_ident (pl, HORN, skill);
721 + do_skill_ident(pl,HORN,skill); 787 break;
722 break;
723 788
724 case SK_DET_CURSE: 789 case SK_DET_CURSE:
725 success = do_skill_detect_curse(pl,skill); 790 success = do_skill_detect_curse (pl, skill);
726 if(success) 791 if (success)
727 new_draw_info(NDI_UNIQUE, 0,pl,"...and discover cursed items!"); 792 new_draw_info (NDI_UNIQUE, 0, pl, "...and discover cursed items!");
728 break; 793 break;
729 794
730 case SK_DET_MAGIC: 795 case SK_DET_MAGIC:
731 success = do_skill_detect_magic(pl,skill); 796 success = do_skill_detect_magic (pl, skill);
732 if(success) 797 if (success)
733 new_draw_info(NDI_UNIQUE, 0,pl, 798 new_draw_info (NDI_UNIQUE, 0, pl, "...and discover items imbued with mystic forces!");
734 "...and discover items imbued with mystic forces!"); 799 break;
735 break;
736 800
737 default: 801 default:
738 LOG(llevError,"Error: bad call to skill_ident()\n"); 802 LOG (llevError, "Error: bad call to skill_ident()\n");
739 return 0; 803 return 0;
740 break; 804 break;
741 } 805 }
742 if(!success) { 806 if (!success)
807 {
743 new_draw_info(NDI_UNIQUE, 0,pl,"...and learn nothing more."); 808 new_draw_info (NDI_UNIQUE, 0, pl, "...and learn nothing more.");
744 } 809 }
745 return success; 810 return success;
746} 811}
747 812
748 813
749/* players using this skill can 'charm' a monster -- 814/* players using this skill can 'charm' a monster --
750 * into working for them. It can only be used on 815 * into working for them. It can only be used on
751 * non-special (see below) 'neutral' creatures. 816 * non-special (see below) 'neutral' creatures.
752 * -b.t. (thomas@astro.psu.edu) 817 * -b.t. (thomas@astro.psu.edu)
753 */ 818 */
754 819
820int
755int use_oratory(object *pl, int dir, object *skill) { 821use_oratory (object *pl, int dir, object *skill)
822{
756 sint16 x=pl->x+freearr_x[dir],y=pl->y+freearr_y[dir]; 823 sint16 x = pl->x + freearr_x[dir], y = pl->y + freearr_y[dir];
757 int mflags,chance; 824 int mflags, chance;
758 object *tmp; 825 object *tmp;
759 mapstruct *m; 826 maptile *m;
760 827
761 if(pl->type!=PLAYER) return 0; /* only players use this skill */ 828 if (pl->type != PLAYER)
829 return 0; /* only players use this skill */
762 m = pl->map; 830 m = pl->map;
763 mflags =get_map_flags(m, &m, x,y, &x, &y); 831 mflags = get_map_flags (m, &m, x, y, &x, &y);
764 if (mflags & P_OUT_OF_MAP) return 0; 832 if (mflags & P_OUT_OF_MAP)
833 return 0;
765 834
766 /* Save some processing - we have the flag already anyways 835 /* Save some processing - we have the flag already anyways
767 */ 836 */
768 if (!(mflags & P_IS_ALIVE)) { 837 if (!(mflags & P_IS_ALIVE))
838 {
769 new_draw_info(NDI_UNIQUE, 0, pl, "There is nothing to orate to."); 839 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to.");
770 return 0; 840 return 0;
771 } 841 }
772 842
773 for(tmp=get_map_ob(m,x,y);tmp;tmp=tmp->above) { 843 for (tmp = get_map_ob (m, x, y); tmp; tmp = tmp->above)
844 {
774 /* can't persuade players - return because there is nothing else 845 /* can't persuade players - return because there is nothing else
775 * on that space to charm. Same for multi space monsters and 846 * on that space to charm. Same for multi space monsters and
776 * special monsters - we don't allow them to be charmed, and there 847 * special monsters - we don't allow them to be charmed, and there
777 * is no reason to do further processing since they should be the 848 * is no reason to do further processing since they should be the
778 * only monster on the space. 849 * only monster on the space.
779 */ 850 */
780 if(tmp->type==PLAYER) return 0; 851 if (tmp->type == PLAYER)
852 return 0;
781 if(tmp->more || tmp->head) return 0; 853 if (tmp->more || tmp->head)
782 if(tmp->msg) return 0; 854 return 0;
855 if (tmp->msg)
856 return 0;
783 857
784 if(QUERY_FLAG(tmp,FLAG_MONSTER)) break; 858 if (QUERY_FLAG (tmp, FLAG_MONSTER))
859 break;
785 } 860 }
786 861
787 if (!tmp) { 862 if (!tmp)
863 {
788 new_draw_info(NDI_UNIQUE, 0, pl, "There is nothing to orate to."); 864 new_draw_info (NDI_UNIQUE, 0, pl, "There is nothing to orate to.");
789 return 0; 865 return 0;
790 } 866 }
791 867
792 new_draw_info_format(NDI_UNIQUE, 868 new_draw_info_format (NDI_UNIQUE, 0, pl, "You orate to the %s.", query_name (tmp));
793 0,pl, "You orate to the %s.",query_name(tmp));
794 869
795 /* the following conditions limit who may be 'charmed' */ 870 /* the following conditions limit who may be 'charmed' */
796 871
797 /* it's hostile! */ 872 /* it's hostile! */
798 if(!QUERY_FLAG(tmp,FLAG_UNAGGRESSIVE) && !QUERY_FLAG(tmp, FLAG_FRIENDLY)) { 873 if (!QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
799 new_draw_info_format(NDI_UNIQUE, 0,pl,
800 "Too bad the %s isn't listening!\n",query_name(tmp));
801 return 0;
802 } 874 {
875 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp));
876 return 0;
877 }
803 878
804 /* it's already allied! */ 879 /* it's already allied! */
805 if(QUERY_FLAG(tmp,FLAG_FRIENDLY)&&(tmp->attack_movement==PETMOVE)){ 880 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && (tmp->attack_movement == PETMOVE))
881 {
806 if(get_owner(tmp)==pl) { 882 if (get_owner (tmp) == pl)
807 new_draw_info(NDI_UNIQUE, 0,pl, 883 {
808 "Your follower loves your speech.\n"); 884 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n");
809 return 0; 885 return 0;
886 }
810 } else if (skill->level > tmp->level) { 887 else if (skill->level > tmp->level)
888 {
811 /* you steal the follower. Perhaps we should really look at the 889 /* you steal the follower. Perhaps we should really look at the
812 * level of the owner above? 890 * level of the owner above?
813 */ 891 */
814 set_owner(tmp,pl); 892 set_owner (tmp, pl);
815 new_draw_info_format(NDI_UNIQUE, 0,pl, 893 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to follow you instead!\n", query_name (tmp));
816 "You convince the %s to follow you instead!\n",
817 query_name(tmp));
818 /* Abuse fix - don't give exp since this can otherwise 894 /* Abuse fix - don't give exp since this can otherwise
819 * be used by a couple players to gets lots of exp. 895 * be used by a couple players to gets lots of exp.
820 */ 896 */
821 return 0; 897 return 0;
822 } else { 898 }
899 else
900 {
823 /* In this case, you can't steal it from the other player */ 901 /* In this case, you can't steal it from the other player */
824 return 0; 902 return 0;
825 } 903 }
826 } /* Creature was already a pet of someone */ 904 } /* Creature was already a pet of someone */
827 905
828 chance=skill->level*2+(pl->stats.Cha-2*tmp->stats.Int)/2; 906 chance = skill->level * 2 + (pl->stats.Cha - 2 * tmp->stats.Int) / 2;
829 907
830 /* Ok, got a 'sucker' lets try to make them a follower */ 908 /* Ok, got a 'sucker' lets try to make them a follower */
831 if(chance>0 && tmp->level<(random_roll(0, chance-1, pl, PREFER_HIGH)-1)) { 909 if (chance > 0 && tmp->level < (random_roll (0, chance - 1, pl, PREFER_HIGH) - 1))
832 new_draw_info_format(NDI_UNIQUE, 0,pl, 910 {
833 "You convince the %s to become your follower.\n", 911 new_draw_info_format (NDI_UNIQUE, 0, pl, "You convince the %s to become your follower.\n", query_name (tmp));
834 query_name(tmp));
835 912
836 set_owner(tmp,pl); 913 set_owner (tmp, pl);
837 tmp->stats.exp = 0; 914 tmp->stats.exp = 0;
838 add_friendly_object(tmp); 915 add_friendly_object (tmp);
839 SET_FLAG(tmp,FLAG_FRIENDLY); 916 SET_FLAG (tmp, FLAG_FRIENDLY);
840 tmp->attack_movement = PETMOVE; 917 tmp->attack_movement = PETMOVE;
841 return calc_skill_exp(pl,tmp, skill); 918 return calc_skill_exp (pl, tmp, skill);
842 } 919 }
843 /* Charm failed. Creature may be angry now */ 920 /* Charm failed. Creature may be angry now */
844 else if((skill->level+((pl->stats.Cha-10)/2)) < random_roll(1, 2*tmp->level, pl, PREFER_LOW)) { 921 else if ((skill->level + ((pl->stats.Cha - 10) / 2)) < random_roll (1, 2 * tmp->level, pl, PREFER_LOW))
845 new_draw_info_format(NDI_UNIQUE, 0,pl, 922 {
846 "Your speech angers the %s!\n",query_name(tmp)); 923 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your speech angers the %s!\n", query_name (tmp));
847 if(QUERY_FLAG(tmp,FLAG_FRIENDLY)) { 924 if (QUERY_FLAG (tmp, FLAG_FRIENDLY))
925 {
848 CLEAR_FLAG(tmp,FLAG_FRIENDLY); 926 CLEAR_FLAG (tmp, FLAG_FRIENDLY);
849 remove_friendly_object(tmp); 927 remove_friendly_object (tmp);
850 tmp->attack_movement = 0; /* needed? */ 928 tmp->attack_movement = 0; /* needed? */
851 } 929 }
852 CLEAR_FLAG(tmp,FLAG_UNAGGRESSIVE); 930 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
853 } 931 }
854 return 0; /* Fall through - if we get here, we didn't charm anything */ 932 return 0; /* Fall through - if we get here, we didn't charm anything */
855} 933}
856 934
857/* Singing() -this skill allows the player to pacify nearby creatures. 935/* Singing() -this skill allows the player to pacify nearby creatures.
858 * There are few limitations on who/what kind of 936 * There are few limitations on who/what kind of
859 * non-player creatures that may be pacified. Right now, a player 937 * non-player creatures that may be pacified. Right now, a player
862 * may only pacify a creature once. 940 * may only pacify a creature once.
863 * BTW, I appologize for the naming of the skill, I couldnt think 941 * BTW, I appologize for the naming of the skill, I couldnt think
864 * of anything better! -b.t. 942 * of anything better! -b.t.
865 */ 943 */
866 944
945int
867int singing(object *pl, int dir, object *skill) { 946singing (object *pl, int dir, object *skill)
947{
868 int i,exp = 0,chance, mflags; 948 int i, exp = 0, chance, mflags;
869 object *tmp; 949 object *tmp;
870 mapstruct *m; 950 maptile *m;
871 sint16 x, y; 951 sint16 x, y;
872 952
873 if(pl->type!=PLAYER) return 0; /* only players use this skill */ 953 if (pl->type != PLAYER)
954 return 0; /* only players use this skill */
874 955
875 new_draw_info_format(NDI_UNIQUE,0,pl, "You sing."); 956 new_draw_info_format (NDI_UNIQUE, 0, pl, "You sing.");
876 for(i=0;i<MIN(skill->level,SIZEOFFREE);i++) { 957 for (i = 0; i < MIN (skill->level, SIZEOFFREE); i++)
958 {
877 x = pl->x+freearr_x[i]; 959 x = pl->x + freearr_x[i];
878 y = pl->y+freearr_y[i]; 960 y = pl->y + freearr_y[i];
879 m = pl->map; 961 m = pl->map;
880 962
881 mflags =get_map_flags(m, &m, x,y, &x, &y); 963 mflags = get_map_flags (m, &m, x, y, &x, &y);
882 if (mflags & P_OUT_OF_MAP) continue; 964 if (mflags & P_OUT_OF_MAP)
965 continue;
883 if (!(mflags & P_IS_ALIVE)) continue; 966 if (!(mflags & P_IS_ALIVE))
967 continue;
884 968
885 for(tmp=get_map_ob(m, x, y); tmp;tmp=tmp->above) { 969 for (tmp = get_map_ob (m, x, y); tmp; tmp = tmp->above)
970 {
886 if(QUERY_FLAG(tmp,FLAG_MONSTER)) break; 971 if (QUERY_FLAG (tmp, FLAG_MONSTER))
972 break;
887 /* can't affect players */ 973 /* can't affect players */
888 if(tmp->type==PLAYER) break; 974 if (tmp->type == PLAYER)
889 } 975 break;
976 }
890 977
891 /* Whole bunch of checks to see if this is a type of monster that would 978 /* Whole bunch of checks to see if this is a type of monster that would
892 * listen to singing. 979 * listen to singing.
893 */ 980 */
894 if (tmp && QUERY_FLAG(tmp, FLAG_MONSTER) && 981 if (tmp && QUERY_FLAG (tmp, FLAG_MONSTER) && !QUERY_FLAG (tmp, FLAG_NO_STEAL) && /* Been charmed or abused before */
895 !QUERY_FLAG(tmp, FLAG_NO_STEAL) && /* Been charmed or abused before */
896 !QUERY_FLAG(tmp, FLAG_SPLITTING) && /* no ears */ 982 !QUERY_FLAG (tmp, FLAG_SPLITTING) && /* no ears */
897 !QUERY_FLAG(tmp, FLAG_HITBACK) && /* was here before */ 983 !QUERY_FLAG (tmp, FLAG_HITBACK) && /* was here before */
898 (tmp->level <= skill->level) && 984 (tmp->level <= skill->level) && (!tmp->head) && !QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && /* already calm */
899 (!tmp->head) && 985 !QUERY_FLAG (tmp, FLAG_FRIENDLY))
900 !QUERY_FLAG(tmp, FLAG_UNDEAD) && 986 { /* already calm */
901 !QUERY_FLAG(tmp,FLAG_UNAGGRESSIVE) && /* already calm */
902 !QUERY_FLAG(tmp,FLAG_FRIENDLY)) { /* already calm */
903 987
904 /* stealing isn't really related (although, maybe it should 988 /* stealing isn't really related (although, maybe it should
905 * be). This is mainly to prevent singing to the same monster 989 * be). This is mainly to prevent singing to the same monster
906 * over and over again and getting exp for it. 990 * over and over again and getting exp for it.
907 */ 991 */
908 chance=skill->level*2+(pl->stats.Cha-5-tmp->stats.Int)/2; 992 chance = skill->level * 2 + (pl->stats.Cha - 5 - tmp->stats.Int) / 2;
909 if(chance && tmp->level*2<random_roll(0, chance-1, pl, PREFER_HIGH)) { 993 if (chance && tmp->level * 2 < random_roll (0, chance - 1, pl, PREFER_HIGH))
994 {
910 SET_FLAG(tmp,FLAG_UNAGGRESSIVE); 995 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
911 new_draw_info_format(NDI_UNIQUE, 0,pl, 996 new_draw_info_format (NDI_UNIQUE, 0, pl, "You calm down the %s\n", query_name (tmp));
912 "You calm down the %s\n",query_name(tmp));
913 /* Give exp only if they are not aware */ 997 /* Give exp only if they are not aware */
914 if(!QUERY_FLAG(tmp,FLAG_NO_STEAL)) 998 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL))
915 exp += calc_skill_exp(pl,tmp, skill); 999 exp += calc_skill_exp (pl, tmp, skill);
916 SET_FLAG(tmp,FLAG_NO_STEAL); 1000 SET_FLAG (tmp, FLAG_NO_STEAL);
917 } else { 1001 }
918 new_draw_info_format(NDI_UNIQUE, 0,pl, 1002 else
919 "Too bad the %s isn't listening!\n",query_name(tmp)); 1003 {
1004 new_draw_info_format (NDI_UNIQUE, 0, pl, "Too bad the %s isn't listening!\n", query_name (tmp));
920 SET_FLAG(tmp,FLAG_NO_STEAL); 1005 SET_FLAG (tmp, FLAG_NO_STEAL);
1006 }
1007 }
921 } 1008 }
922 }
923 }
924 return exp; 1009 return exp;
925} 1010}
926 1011
927/* The find_traps skill (aka, search). Checks for traps 1012/* The find_traps skill (aka, search). Checks for traps
928 * on the spaces or in certain objects 1013 * on the spaces or in certain objects
929 */ 1014 */
930 1015
1016int
931int find_traps (object *pl, object *skill) { 1017find_traps (object *pl, object *skill)
1018{
932 object *tmp,*tmp2; 1019 object *tmp, *tmp2;
933 int i,expsum=0, mflags; 1020 int i, expsum = 0, mflags;
934 sint16 x,y; 1021 sint16 x, y;
935 mapstruct *m; 1022 maptile *m;
936 1023
937 /* First we search all around us for runes and traps, which are 1024 /* First we search all around us for runes and traps, which are
938 * all type RUNE 1025 * all type RUNE
939 */ 1026 */
940 1027
941 for(i=0;i<9;i++) { 1028 for (i = 0; i < 9; i++)
1029 {
942 x = pl->x+freearr_x[i]; 1030 x = pl->x + freearr_x[i];
943 y = pl->y+freearr_y[i]; 1031 y = pl->y + freearr_y[i];
944 m = pl->map; 1032 m = pl->map;
945 1033
946 mflags =get_map_flags(m, &m, x,y, &x, &y); 1034 mflags = get_map_flags (m, &m, x, y, &x, &y);
947 if (mflags & P_OUT_OF_MAP) continue; 1035 if (mflags & P_OUT_OF_MAP)
1036 continue;
948 1037
949 /* Check everything in the square for trapness */ 1038 /* Check everything in the square for trapness */
950 for(tmp = get_map_ob(m, x, y); tmp!=NULL;tmp=tmp->above) { 1039 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above)
1040 {
951 1041
952 /* And now we'd better do an inventory traversal of each 1042 /* And now we'd better do an inventory traversal of each
953 * of these objects' inventory 1043 * of these objects' inventory
954 * We can narrow this down a bit - no reason to search through 1044 * We can narrow this down a bit - no reason to search through
955 * the players inventory or monsters for that matter. 1045 * the players inventory or monsters for that matter.
956 */ 1046 */
957 if (tmp->type != PLAYER && !QUERY_FLAG(tmp, FLAG_MONSTER)) { 1047 if (tmp->type != PLAYER && !QUERY_FLAG (tmp, FLAG_MONSTER))
1048 {
958 for(tmp2=tmp->inv;tmp2!=NULL;tmp2=tmp2->below) 1049 for (tmp2 = tmp->inv; tmp2 != NULL; tmp2 = tmp2->below)
959 if(tmp2->type==RUNE || tmp2->type == TRAP) 1050 if (tmp2->type == RUNE || tmp2->type == TRAP)
960 if(trap_see(pl,tmp2)) { 1051 if (trap_see (pl, tmp2))
961 trap_show(tmp2,tmp); 1052 {
962 if(tmp2->stats.Cha>1) { 1053 trap_show (tmp2, tmp);
963 if (!tmp2->owner || tmp2->owner->type!=PLAYER) 1054 if (tmp2->stats.Cha > 1)
1055 {
1056 if (!tmp2->owner || tmp2->owner->type != PLAYER)
964 expsum += calc_skill_exp(pl,tmp2, skill); 1057 expsum += calc_skill_exp (pl, tmp2, skill);
965 1058
966 tmp2->stats.Cha = 1; /* unhide the trap */ 1059 tmp2->stats.Cha = 1; /* unhide the trap */
967 } 1060 }
968 } 1061 }
969 } 1062 }
970 if((tmp->type==RUNE || tmp->type == TRAP) && trap_see(pl,tmp)) { 1063 if ((tmp->type == RUNE || tmp->type == TRAP) && trap_see (pl, tmp))
971 trap_show(tmp,tmp); 1064 {
972 if(tmp->stats.Cha>1) { 1065 trap_show (tmp, tmp);
1066 if (tmp->stats.Cha > 1)
1067 {
973 if (!tmp->owner || tmp->owner->type!=PLAYER) 1068 if (!tmp->owner || tmp->owner->type != PLAYER)
974 expsum += calc_skill_exp(pl,tmp, skill); 1069 expsum += calc_skill_exp (pl, tmp, skill);
975 tmp->stats.Cha = 1; /* unhide the trap */ 1070 tmp->stats.Cha = 1; /* unhide the trap */
976 } 1071 }
1072 }
1073 }
977 } 1074 }
978 }
979 }
980 new_draw_info(NDI_BLACK, 0, pl, "You search the area."); 1075 new_draw_info (NDI_BLACK, 0, pl, "You search the area.");
981 return expsum; 1076 return expsum;
982} 1077}
983 1078
984/* remove_trap() - This skill will disarm any previously discovered trap 1079/* remove_trap() - This skill will disarm any previously discovered trap
985 * the algorithm is based (almost totally) on the old command_disarm() - b.t. 1080 * the algorithm is based (almost totally) on the old command_disarm() - b.t.
986 */ 1081 */
987 1082
1083int
988int remove_trap (object *op, int dir, object *skill) { 1084remove_trap (object *op, int dir, object *skill)
1085{
989 object *tmp,*tmp2; 1086 object *tmp, *tmp2;
990 int i,success=0,mflags; 1087 int i, success = 0, mflags;
991 mapstruct *m; 1088 maptile *m;
992 sint16 x,y; 1089 sint16 x, y;
993 1090
994 for(i=0;i<9;i++) { 1091 for (i = 0; i < 9; i++)
1092 {
995 x = op->x + freearr_x[i]; 1093 x = op->x + freearr_x[i];
996 y = op->y + freearr_y[i]; 1094 y = op->y + freearr_y[i];
997 m = op->map; 1095 m = op->map;
998 1096
999 mflags =get_map_flags(m, &m, x,y, &x, &y); 1097 mflags = get_map_flags (m, &m, x, y, &x, &y);
1000 if (mflags & P_OUT_OF_MAP) continue; 1098 if (mflags & P_OUT_OF_MAP)
1099 continue;
1001 1100
1002 /* Check everything in the square for trapness */ 1101 /* Check everything in the square for trapness */
1003 for(tmp = get_map_ob(m,x,y);tmp!=NULL;tmp=tmp->above) { 1102 for (tmp = get_map_ob (m, x, y); tmp != NULL; tmp = tmp->above)
1103 {
1004 /* And now we'd better do an inventory traversal of each 1104 /* And now we'd better do an inventory traversal of each
1005 * of these objects inventory. Like above, only 1105 * of these objects inventory. Like above, only
1006 * do this for interesting objects. 1106 * do this for interesting objects.
1007 */ 1107 */
1008 1108
1009 if (tmp->type != PLAYER && !QUERY_FLAG(tmp, FLAG_MONSTER)) { 1109 if (tmp->type != PLAYER && !QUERY_FLAG (tmp, FLAG_MONSTER))
1110 {
1010 for(tmp2=tmp->inv;tmp2!=NULL;tmp2=tmp2->below) 1111 for (tmp2 = tmp->inv; tmp2 != NULL; tmp2 = tmp2->below)
1112 if ((tmp2->type == RUNE || tmp2->type == TRAP) && tmp2->stats.Cha <= 1)
1113 {
1114 trap_show (tmp2, tmp);
1115 if (trap_disarm (op, tmp2, 1, skill) && (!tmp2->owner || tmp2->owner->type != PLAYER))
1116 {
1117 tmp->stats.exp = tmp->stats.Cha * tmp->level;
1118 success += calc_skill_exp (op, tmp2, skill);
1119 }
1120 }
1121 }
1011 if((tmp2->type==RUNE || tmp2->type == TRAP) && tmp2->stats.Cha<=1) { 1122 if ((tmp->type == RUNE || tmp->type == TRAP) && tmp->stats.Cha <= 1)
1012 trap_show(tmp2,tmp); 1123 {
1124 trap_show (tmp, tmp);
1013 if(trap_disarm(op,tmp2,1, skill) && (!tmp2->owner || tmp2->owner->type!=PLAYER)) { 1125 if (trap_disarm (op, tmp, 1, skill) && (!tmp->owner || tmp->owner->type != PLAYER))
1126 {
1014 tmp->stats.exp = tmp->stats.Cha * tmp->level; 1127 tmp->stats.exp = tmp->stats.Cha * tmp->level;
1015 success += calc_skill_exp(op,tmp2, skill); 1128 success += calc_skill_exp (op, tmp, skill);
1016 } 1129 }
1017 } 1130 }
1131 }
1018 } 1132 }
1019 if((tmp->type==RUNE || tmp->type==TRAP) && tmp->stats.Cha<=1) {
1020 trap_show(tmp,tmp);
1021 if (trap_disarm(op,tmp,1,skill) && (!tmp->owner || tmp->owner->type!=PLAYER)) {
1022 tmp->stats.exp = tmp->stats.Cha * tmp->level;
1023 success += calc_skill_exp(op,tmp,skill);
1024 }
1025 }
1026 }
1027 }
1028 return success; 1133 return success;
1029} 1134}
1030 1135
1031 1136
1032/* pray() - when this skill is called from do_skill(), it allows 1137/* pray() - when this skill is called from do_skill(), it allows
1033 * the player to regain lost grace points at a faster rate. -b.t. 1138 * the player to regain lost grace points at a faster rate. -b.t.
1035 * such that if it returns true, player gets exp in that skill. This 1140 * such that if it returns true, player gets exp in that skill. This
1036 * the effect here can be done on demand, we probably don't want to 1141 * the effect here can be done on demand, we probably don't want to
1037 * give infinite exp by returning true in any cases. 1142 * give infinite exp by returning true in any cases.
1038 */ 1143 */
1039 1144
1145int
1040int pray (object *pl, object *skill) { 1146pray (object *pl, object *skill)
1147{
1041 char buf[MAX_BUF]; 1148 char buf[MAX_BUF];
1042 object *tmp; 1149 object *tmp;
1043 1150
1044 if(pl->type!=PLAYER) return 0; 1151 if (pl->type != PLAYER)
1045
1046 strcpy(buf,"You pray.");
1047
1048 /* Check all objects - we could stop at floor objects,
1049 * but if someone buries an altar, I don't see a problem with
1050 * going through all the objects, and it shouldn't be much slower
1051 * than extra checks on object attributes.
1052 */
1053 for (tmp=pl->below; tmp!=NULL; tmp=tmp->below) {
1054 /* Only if the altar actually belongs to someone do you get special benefits */
1055 if(tmp && tmp->type==HOLY_ALTAR && tmp->other_arch) {
1056 sprintf(buf,"You pray over the %s.",tmp->name);
1057 pray_at_altar(pl,tmp, skill);
1058 break; /* Only pray at one altar */
1059 }
1060 }
1061
1062 new_draw_info(NDI_BLACK,0,pl,buf);
1063
1064 if(pl->stats.grace < pl->stats.maxgrace) {
1065 pl->stats.grace++;
1066 pl->last_grace = -1;
1067 }
1068 return 0; 1152 return 0;
1153
1154 strcpy (buf, "You pray.");
1155
1156 /* Check all objects - we could stop at floor objects,
1157 * but if someone buries an altar, I don't see a problem with
1158 * going through all the objects, and it shouldn't be much slower
1159 * than extra checks on object attributes.
1160 */
1161 for (tmp = pl->below; tmp != NULL; tmp = tmp->below)
1162 {
1163 /* Only if the altar actually belongs to someone do you get special benefits */
1164 if (tmp && tmp->type == HOLY_ALTAR && tmp->other_arch)
1165 {
1166 sprintf (buf, "You pray over the %s.", &tmp->name);
1167 pray_at_altar (pl, tmp, skill);
1168 break; /* Only pray at one altar */
1169 }
1170 }
1171
1172 new_draw_info (NDI_BLACK, 0, pl, buf);
1173
1174 if (pl->stats.grace < pl->stats.maxgrace)
1175 {
1176 pl->stats.grace++;
1177 pl->last_grace = -1;
1178 }
1179 return 0;
1069} 1180}
1070 1181
1071/* This skill allows the player to regain a few sp or hp for a 1182/* This skill allows the player to regain a few sp or hp for a
1072 * brief period of concentration. No armour or weapons may be 1183 * brief period of concentration. No armour or weapons may be
1073 * wielded/applied for this to work. The amount of time needed 1184 * wielded/applied for this to work. The amount of time needed
1074 * to concentrate and the # of points regained is dependant on 1185 * to concentrate and the # of points regained is dependant on
1075 * the level of the user. - b.t. thomas@astro.psu.edu 1186 * the level of the user. - b.t. thomas@astro.psu.edu
1076 */ 1187 */
1077 1188
1189void
1078void meditate (object *pl, object *skill) { 1190meditate (object *pl, object *skill)
1191{
1079 object *tmp; 1192 object *tmp;
1080 1193
1081 if(pl->type!=PLAYER) return; /* players only */ 1194 if (pl->type != PLAYER)
1195 return; /* players only */
1082 1196
1083 /* check if pl has removed encumbering armour and weapons */ 1197 /* check if pl has removed encumbering armour and weapons */
1084 if(QUERY_FLAG(pl,FLAG_READY_WEAPON) && (skill->level<6)) { 1198 if (QUERY_FLAG (pl, FLAG_READY_WEAPON) && (skill->level < 6))
1085 new_draw_info(NDI_UNIQUE,0,pl, 1199 {
1086 "You can't concentrate while wielding a weapon!\n"); 1200 new_draw_info (NDI_UNIQUE, 0, pl, "You can't concentrate while wielding a weapon!\n");
1087 return; 1201 return;
1088 } else { 1202 }
1203 else
1204 {
1089 for(tmp=pl->inv;tmp;tmp=tmp->below) 1205 for (tmp = pl->inv; tmp; tmp = tmp->below)
1090 if (( (tmp->type==ARMOUR && skill->level<12) 1206 if (((tmp->type == ARMOUR && skill->level < 12)
1091 || (tmp->type==HELMET && skill->level<10) 1207 || (tmp->type == HELMET && skill->level < 10)
1092 || (tmp->type==SHIELD && skill->level<6) 1208 || (tmp->type == SHIELD && skill->level < 6)
1093 || (tmp->type==BOOTS && skill->level<4) 1209 || (tmp->type == BOOTS && skill->level < 4) || (tmp->type == GLOVES && skill->level < 2)) && QUERY_FLAG (tmp, FLAG_APPLIED))
1094 || (tmp->type==GLOVES && skill->level<2) ) 1210 {
1095 && QUERY_FLAG(tmp,FLAG_APPLIED)) { 1211 new_draw_info (NDI_UNIQUE, 0, pl, "You can't concentrate while wearing so much armour!\n");
1096 new_draw_info(NDI_UNIQUE,0,pl, 1212 return;
1097 "You can't concentrate while wearing so much armour!\n"); 1213 }
1098 return;
1099 }
1100 } 1214 }
1101 1215
1102 /* ok let's meditate! Spell points are regained first, then once 1216 /* ok let's meditate! Spell points are regained first, then once
1103 * they are maxed we get back hp. Actual incrementing of values 1217 * they are maxed we get back hp. Actual incrementing of values
1104 * is handled by the do_some_living() (in player.c). This way magical 1218 * is handled by the do_some_living() (in player.c). This way magical
1105 * bonuses for healing/sp regeneration are included properly 1219 * bonuses for healing/sp regeneration are included properly
1106 * No matter what, we will eat up some playing time trying to 1220 * No matter what, we will eat up some playing time trying to
1107 * meditate. (see 'factor' variable for what sets the amount of time) 1221 * meditate. (see 'factor' variable for what sets the amount of time)
1108 */ 1222 */
1109 1223
1110 new_draw_info(NDI_BLACK,0,pl, "You meditate."); 1224 new_draw_info (NDI_BLACK, 0, pl, "You meditate.");
1111 1225
1112 if(pl->stats.sp < pl->stats.maxsp) { 1226 if (pl->stats.sp < pl->stats.maxsp)
1227 {
1113 pl->stats.sp++; 1228 pl->stats.sp++;
1114 pl->last_sp = -1; 1229 pl->last_sp = -1;
1230 }
1115 } else if (pl->stats.hp < pl->stats.maxhp) { 1231 else if (pl->stats.hp < pl->stats.maxhp)
1232 {
1116 pl->stats.hp++; 1233 pl->stats.hp++;
1117 pl->last_heal = -1; 1234 pl->last_heal = -1;
1118 } 1235 }
1119} 1236}
1120 1237
1121/* write_note() - this routine allows players to inscribe messages in 1238/* write_note() - this routine allows players to inscribe messages in
1122 * ordinary 'books' (anything that is type BOOK). b.t. 1239 * ordinary 'books' (anything that is type BOOK). b.t.
1123 */ 1240 */
1124 1241
1242static int
1125static int write_note(object *pl, object *item, const char *msg, object *skill) { 1243write_note (object *pl, object *item, const char *msg, object *skill)
1244{
1126 char buf[1024]; 1245 char buf[1024];
1127 object *newBook = NULL; 1246 object *newBook = NULL;
1128 1247
1129 /* a pair of sanity checks */ 1248 /* a pair of sanity checks */
1130 if(!item||item->type!=BOOK) return 0; 1249 if (!item || item->type != BOOK)
1131
1132 if(!msg) {
1133 new_draw_info(NDI_UNIQUE,0,pl,"No message to write!");
1134 new_draw_info_format(NDI_UNIQUE,0,pl,"Usage: use_skill %s <message>",
1135 skill->skill);
1136 return 0;
1137 }
1138 if (strcasestr_local(msg, "endmsg")) {
1139 new_draw_info(NDI_UNIQUE,0,pl,"Trying to cheat now are we?");
1140 return 0;
1141 }
1142
1143 /* Lauwenmark: Handle for plugin book writing (trigger) event */
1144 if (execute_event(item, EVENT_TRIGGER,pl,NULL,msg,SCRIPT_FIX_ALL)!=0)
1145 return strlen(msg);
1146
1147 buf[0] = 0;
1148 if(!book_overflow(item->msg,msg,sizeof (buf))) { /* add msg string to book */
1149 if(item->msg)
1150 strcpy(buf,item->msg);
1151
1152 strcat(buf,msg);
1153 strcat(buf,"\n"); /* new msg needs a LF */
1154 if(item->nrof > 1) {
1155 newBook = get_object();
1156 copy_object(item, newBook);
1157 decrease_ob(item);
1158 esrv_send_item(pl, item);
1159 newBook->nrof = 1;
1160 if (newBook->msg) free_string(newBook->msg);
1161 newBook->msg = add_string(buf);
1162 newBook = insert_ob_in_ob(newBook, pl);
1163 esrv_send_item(pl, newBook);
1164 } else {
1165 if (item->msg) free_string(item->msg);
1166 item->msg=add_string(buf);
1167 /* This shouldn't be necessary - the object hasn't changed in any
1168 * visible way
1169 */
1170 /* esrv_send_item(pl, item);*/
1171 }
1172 new_draw_info_format(NDI_UNIQUE,0,pl, "You write in the %s.",
1173 query_short_name(item));
1174 return strlen(msg);
1175 } else
1176 new_draw_info_format(NDI_UNIQUE,0,pl,
1177 "Your message won't fit in the %s!",
1178 query_short_name(item));
1179
1180 return 0; 1250 return 0;
1251
1252 if (!msg)
1253 {
1254 new_draw_info (NDI_UNIQUE, 0, pl, "No message to write!");
1255 new_draw_info_format (NDI_UNIQUE, 0, pl, "Usage: use_skill %s <message>", &skill->skill);
1256 return 0;
1257 }
1258 if (strcasestr_local (msg, "endmsg"))
1259 {
1260 new_draw_info (NDI_UNIQUE, 0, pl, "Trying to cheat now are we?");
1261 return 0;
1262 }
1263
1264 if (INVOKE_OBJECT (INSCRIBE_NOTE, item, ARG_PLAYER (pl->contr), ARG_STRING (msg), ARG_OBJECT (skill)))
1265 return strlen (msg);
1266
1267 buf[0] = 0;
1268 if (!book_overflow (item->msg, msg, sizeof (buf)))
1269 { /* add msg string to book */
1270 if (item->msg)
1271 strcpy (buf, item->msg);
1272
1273 strcat (buf, msg);
1274 strcat (buf, "\n"); /* new msg needs a LF */
1275 if (item->nrof > 1)
1276 {
1277 newBook = get_object ();
1278 copy_object (item, newBook);
1279 decrease_ob (item);
1280 esrv_send_item (pl, item);
1281 newBook->nrof = 1;
1282 newBook->msg = buf;
1283 newBook = insert_ob_in_ob (newBook, pl);
1284 esrv_send_item (pl, newBook);
1285 }
1286 else
1287 {
1288 item->msg = buf;
1289 /* This shouldn't be necessary - the object hasn't changed in any
1290 * visible way
1291 */
1292 /* esrv_send_item(pl, item); */
1293 }
1294 new_draw_info_format (NDI_UNIQUE, 0, pl, "You write in the %s.", query_short_name (item));
1295 return strlen (msg);
1296 }
1297 else
1298 new_draw_info_format (NDI_UNIQUE, 0, pl, "Your message won't fit in the %s!", query_short_name (item));
1299
1300 return 0;
1181} 1301}
1182 1302
1183/* write_scroll() - this routine allows players to inscribe spell scrolls 1303/* write_scroll() - this routine allows players to inscribe spell scrolls
1184 * of spells which they know. Backfire effects are possible with the 1304 * of spells which they know. Backfire effects are possible with the
1185 * severity of the backlash correlated with the difficulty of the scroll 1305 * severity of the backlash correlated with the difficulty of the scroll
1186 * that is attempted. -b.t. thomas@astro.psu.edu 1306 * that is attempted. -b.t. thomas@astro.psu.edu
1187 */ 1307 */
1188 1308
1309static int
1189static int write_scroll (object *pl, object *scroll, object *skill) { 1310write_scroll (object *pl, object *scroll, object *skill)
1311{
1190 int success=0,confused=0; 1312 int success = 0, confused = 0;
1191 object *newscroll, *chosen_spell, *tmp; 1313 object *newscroll, *chosen_spell, *tmp;
1192 1314
1193 /* this is a sanity check */ 1315 /* this is a sanity check */
1194 if (scroll->type!=SCROLL) { 1316 if (scroll->type != SCROLL)
1317 {
1195 new_draw_info(NDI_UNIQUE,0,pl,"A spell can only be inscribed into a scroll!"); 1318 new_draw_info (NDI_UNIQUE, 0, pl, "A spell can only be inscribed into a scroll!");
1196 return 0; 1319 return 0;
1197 } 1320 }
1198 1321
1199 /* Check if we are ready to attempt inscription */ 1322 /* Check if we are ready to attempt inscription */
1200 chosen_spell=pl->contr->ranges[range_magic]; 1323 chosen_spell = pl->contr->ranges[range_magic];
1201 if(!chosen_spell) { 1324 if (!chosen_spell)
1202 new_draw_info(NDI_UNIQUE,0,pl,
1203 "You need a spell readied in order to inscribe!");
1204 return 0;
1205 } 1325 {
1326 new_draw_info (NDI_UNIQUE, 0, pl, "You need a spell readied in order to inscribe!");
1327 return 0;
1328 }
1206 if(SP_level_spellpoint_cost(pl,chosen_spell,SPELL_GRACE) > pl->stats.grace) { 1329 if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_GRACE) > pl->stats.grace)
1207 new_draw_info_format(NDI_UNIQUE,0,pl,
1208 "You don't have enough grace to write a scroll of %s.",
1209 chosen_spell->name);
1210 return 0;
1211 } 1330 {
1331 new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough grace to write a scroll of %s.", &chosen_spell->name);
1332 return 0;
1333 }
1212 if(SP_level_spellpoint_cost(pl,chosen_spell,SPELL_MANA) > pl->stats.sp) { 1334 if (SP_level_spellpoint_cost (pl, chosen_spell, SPELL_MANA) > pl->stats.sp)
1213 new_draw_info_format(NDI_UNIQUE,0,pl,
1214 "You don't have enough mana to write a scroll of %s.",
1215 chosen_spell->name);
1216 return 0;
1217 } 1335 {
1336 new_draw_info_format (NDI_UNIQUE, 0, pl, "You don't have enough mana to write a scroll of %s.", &chosen_spell->name);
1337 return 0;
1338 }
1218 1339
1219 /* if there is a spell already on the scroll then player could easily 1340 /* if there is a spell already on the scroll then player could easily
1220 * accidently read it while trying to write the new one. give player 1341 * accidently read it while trying to write the new one. give player
1221 * a 50% chance to overwrite spell at their own level 1342 * a 50% chance to overwrite spell at their own level
1222 */ 1343 */
1223 if((scroll->stats.sp || scroll->inv) && 1344 if ((scroll->stats.sp || scroll->inv) && random_roll (0, scroll->level * 2, pl, PREFER_LOW) > skill->level)
1224 random_roll(0, scroll->level*2, pl, PREFER_LOW)>skill->level) { 1345 {
1225 new_draw_info_format(NDI_UNIQUE,0,pl, 1346 new_draw_info_format (NDI_UNIQUE, 0, pl, "Oops! You accidently read it while trying to write on it.");
1226 "Oops! You accidently read it while trying to write on it.");
1227 manual_apply(pl,scroll,0); 1347 manual_apply (pl, scroll, 0);
1228 return 0; 1348 return 0;
1229 } 1349 }
1230 1350
1231 /* ok, we are ready to try inscription */ 1351 /* ok, we are ready to try inscription */
1232 if(QUERY_FLAG(pl,FLAG_CONFUSED)) confused = 1; 1352 if (QUERY_FLAG (pl, FLAG_CONFUSED))
1353 confused = 1;
1233 1354
1234 /* Lost mana/grace no matter what */ 1355 /* Lost mana/grace no matter what */
1235 pl->stats.grace-=SP_level_spellpoint_cost(pl,chosen_spell,SPELL_GRACE); 1356 pl->stats.grace -= SP_level_spellpoint_cost (pl, chosen_spell, SPELL_GRACE);
1236 pl->stats.sp-=SP_level_spellpoint_cost(pl,chosen_spell,SPELL_MANA); 1357 pl->stats.sp -= SP_level_spellpoint_cost (pl, chosen_spell, SPELL_MANA);
1237 1358
1238 if (random_roll(0, chosen_spell->level*4-1, pl, PREFER_LOW) < skill->level) { 1359 if (random_roll (0, chosen_spell->level * 4 - 1, pl, PREFER_LOW) < skill->level)
1360 {
1239 if (scroll->nrof > 1) { 1361 if (scroll->nrof > 1)
1362 {
1240 newscroll = get_object(); 1363 newscroll = get_object ();
1241 copy_object(scroll, newscroll); 1364 copy_object (scroll, newscroll);
1242 decrease_ob(scroll); 1365 decrease_ob (scroll);
1243 newscroll->nrof = 1; 1366 newscroll->nrof = 1;
1244 } else { 1367 }
1368 else
1369 {
1245 newscroll = scroll; 1370 newscroll = scroll;
1246 } 1371 }
1247 1372
1248 if(!confused) { 1373 if (!confused)
1374 {
1249 newscroll->level= MAX(skill->level, chosen_spell->level); 1375 newscroll->level = MAX (skill->level, chosen_spell->level);
1250 new_draw_info(NDI_UNIQUE,0,pl, 1376 new_draw_info (NDI_UNIQUE, 0, pl, "You succeed in writing a new scroll.");
1251 "You succeed in writing a new scroll."); 1377 }
1252 } else { 1378 else
1379 {
1253 chosen_spell = find_random_spell_in_ob(pl, NULL); 1380 chosen_spell = find_random_spell_in_ob (pl, NULL);
1254 if (!chosen_spell) return 0; 1381 if (!chosen_spell)
1382 return 0;
1255 1383
1256 newscroll->level= MAX(skill->level, chosen_spell->level); 1384 newscroll->level = MAX (skill->level, chosen_spell->level);
1257 new_draw_info(NDI_UNIQUE,0,pl, 1385 new_draw_info (NDI_UNIQUE, 0, pl, "In your confused state, you write down some odd spell.");
1258 "In your confused state, you write down some odd spell."); 1386 }
1259 }
1260 1387
1261 if (newscroll->inv) { 1388 if (newscroll->inv)
1389 {
1262 object *ninv; 1390 object *ninv;
1263 1391
1264 ninv = newscroll->inv; 1392 ninv = newscroll->inv;
1265 remove_ob(ninv); 1393 remove_ob (ninv);
1266 free_object(ninv); 1394 free_object (ninv);
1267 } 1395 }
1268 tmp = get_object(); 1396 tmp = get_object ();
1269 copy_object(chosen_spell, tmp); 1397 copy_object (chosen_spell, tmp);
1270 insert_ob_in_ob(tmp, newscroll); 1398 insert_ob_in_ob (tmp, newscroll);
1271 1399
1272 /* Same code as from treasure.c - so they can better merge. 1400 /* Same code as from treasure.c - so they can better merge.
1273 * if players want to sell them, so be it. 1401 * if players want to sell them, so be it.
1274 */ 1402 */
1275 newscroll->value = newscroll->arch->clone.value * newscroll->inv->value * 1403 newscroll->value = newscroll->arch->clone.value * newscroll->inv->value * (newscroll->level + 50) / (newscroll->inv->level + 50);
1276 (newscroll->level +50) / (newscroll->inv->level + 50);
1277 newscroll->stats.exp = newscroll->value/5; 1404 newscroll->stats.exp = newscroll->value / 5;
1278 1405
1279 /* wait until finished manipulating the scroll before inserting it */ 1406 /* wait until finished manipulating the scroll before inserting it */
1280 if (newscroll == scroll) 1407 if (newscroll == scroll)
1281 { 1408 {
1282 /* Remove to correctly merge with other items which may exist in inventory */ 1409 /* Remove to correctly merge with other items which may exist in inventory */
1283 remove_ob(newscroll); 1410 remove_ob (newscroll);
1284 esrv_del_item(pl->contr,newscroll->count); 1411 esrv_del_item (pl->contr, newscroll->count);
1285 } 1412 }
1286 newscroll=insert_ob_in_ob(newscroll,pl); 1413 newscroll = insert_ob_in_ob (newscroll, pl);
1287 esrv_send_item(pl, newscroll); 1414 esrv_send_item (pl, newscroll);
1288 success = calc_skill_exp(pl,newscroll, skill); 1415 success = calc_skill_exp (pl, newscroll, skill);
1289 if(!confused) success *= 2; 1416 if (!confused)
1417 success *= 2;
1290 success = success * skill->level; 1418 success = success * skill->level;
1291 return success; 1419 return success;
1292 1420
1293 } else { /* Inscription has failed */ 1421 }
1422 else
1423 { /* Inscription has failed */
1294 1424
1295 if(chosen_spell->level>skill->level || confused) { /*backfire!*/ 1425 if (chosen_spell->level > skill->level || confused)
1296 new_draw_info(NDI_UNIQUE,0,pl, 1426 { /*backfire! */
1297 "Ouch! Your attempt to write a new scroll strains your mind!"); 1427 new_draw_info (NDI_UNIQUE, 0, pl, "Ouch! Your attempt to write a new scroll strains your mind!");
1298 if(random_roll(0, 1, pl, PREFER_LOW)==1) 1428 if (random_roll (0, 1, pl, PREFER_LOW) == 1)
1299 drain_specific_stat(pl,4); 1429 drain_specific_stat (pl, 4);
1300 else { 1430 else
1431 {
1432 confuse_player (pl, pl, 99);
1433 return (-30 * chosen_spell->level);
1434 }
1435 }
1436 else if (random_roll (0, pl->stats.Int - 1, pl, PREFER_HIGH) < 15)
1437 {
1438 new_draw_info (NDI_UNIQUE, 0, pl, "Your attempt to write a new scroll rattles your mind!");
1301 confuse_player(pl,pl,99); 1439 confuse_player (pl, pl, 99);
1302 return (-30*chosen_spell->level); 1440 }
1303 } 1441 else
1304 } else if(random_roll(0, pl->stats.Int-1, pl, PREFER_HIGH) < 15) {
1305 new_draw_info(NDI_UNIQUE,0,pl,
1306 "Your attempt to write a new scroll rattles your mind!");
1307 confuse_player(pl,pl,99);
1308 } else
1309 new_draw_info(NDI_UNIQUE,0,pl,"You fail to write a new scroll."); 1442 new_draw_info (NDI_UNIQUE, 0, pl, "You fail to write a new scroll.");
1310 } 1443 }
1444 return 0;
1445}
1446
1447/* write_on_item() - wrapper for write_note and write_scroll */
1448int
1449write_on_item (object *pl, const char *params, object *skill)
1450{
1451 object *item;
1452 const char *string = params;
1453 int msgtype;
1454 archetype *skat;
1455
1456 if (pl->type != PLAYER)
1311 return 0; 1457 return 0;
1312}
1313 1458
1314/* write_on_item() - wrapper for write_note and write_scroll */
1315int write_on_item (object *pl,const char *params, object *skill) {
1316 object *item;
1317 const char *string=params;
1318 int msgtype;
1319 archetype *skat;
1320
1321 if(pl->type!=PLAYER) return 0;
1322
1323 if (!params) { 1459 if (!params)
1324 params="";
1325 string=params;
1326 } 1460 {
1461 params = "";
1462 string = params;
1463 }
1327 skat = get_archetype_by_type_subtype(SKILL, SK_LITERACY); 1464 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY);
1328 1465
1329 /* Need to be able to read before we can write! */ 1466 /* Need to be able to read before we can write! */
1330 if(!find_skill_by_name(pl,skat->clone.skill)) { 1467 if (!find_skill_by_name (pl, skat->clone.skill))
1331 new_draw_info(NDI_UNIQUE,0,pl,
1332 "You must learn to read before you can write!");
1333 return 0;
1334 } 1468 {
1469 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write!");
1470 return 0;
1471 }
1335 1472
1336 /* if there is a message then it goes in a book and no message means 1473 /* if there is a message then it goes in a book and no message means
1337 * write active spell into the scroll 1474 * write active spell into the scroll
1338 */ 1475 */
1339 msgtype = (string[0]!='\0') ? BOOK : SCROLL; 1476 msgtype = (string[0] != '\0') ? BOOK : SCROLL;
1340 1477
1341 /* find an item of correct type to write on */ 1478 /* find an item of correct type to write on */
1342 if ( !(item = find_marked_object(pl))){ 1479 if (!(item = find_marked_object (pl)))
1480 {
1343 new_draw_info(NDI_UNIQUE,0,pl,"You don't have any marked item to write on."); 1481 new_draw_info (NDI_UNIQUE, 0, pl, "You don't have any marked item to write on.");
1344 return 0; 1482 return 0;
1345 } 1483 }
1346 1484
1347 if(QUERY_FLAG(item,FLAG_UNPAID)) { 1485 if (QUERY_FLAG (item, FLAG_UNPAID))
1348 new_draw_info(NDI_UNIQUE,0,pl,
1349 "You had better pay for that before you write on it.");
1350 return 0;
1351 } 1486 {
1487 new_draw_info (NDI_UNIQUE, 0, pl, "You had better pay for that before you write on it.");
1488 return 0;
1489 }
1352 if (msgtype != item->type) { 1490 if (msgtype != item->type)
1353 new_draw_info_format(NDI_UNIQUE,0,pl,"You have no %s to write on",
1354 msgtype==BOOK ? "book" : "scroll");
1355 return 0;
1356 } 1491 {
1357 1492 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no %s to write on", msgtype == BOOK ? "book" : "scroll");
1358 if (msgtype == SCROLL) {
1359 return write_scroll(pl,item, skill);
1360 } else if (msgtype == BOOK) {
1361 return write_note(pl,item,string, skill);
1362 }
1363 return 0; 1493 return 0;
1494 }
1495
1496 if (msgtype == SCROLL)
1497 {
1498 return write_scroll (pl, item, skill);
1499 }
1500 else if (msgtype == BOOK)
1501 {
1502 return write_note (pl, item, string, skill);
1503 }
1504 return 0;
1364} 1505}
1365 1506
1366 1507
1367 1508
1368/* find_throw_ob() - if we request an object, then 1509/* find_throw_ob() - if we request an object, then
1372 * (that is "throwable", ie no throwing your skills away!) 1513 * (that is "throwable", ie no throwing your skills away!)
1373 * is the object of choice. Also check to see if object is 1514 * is the object of choice. Also check to see if object is
1374 * 'throwable' (ie not applied cursed obj, worn, etc). 1515 * 'throwable' (ie not applied cursed obj, worn, etc).
1375 */ 1516 */
1376 1517
1518static object *
1377static object *find_throw_ob( object *op, const char *request ) { 1519find_throw_ob (object *op, const char *request)
1520{
1378 object *tmp; 1521 object *tmp;
1379 1522
1380 if(!op) { /* safety */ 1523 if (!op)
1524 { /* safety */
1381 LOG(llevError,"find_throw_ob(): confused! have a NULL thrower!\n"); 1525 LOG (llevError, "find_throw_ob(): confused! have a NULL thrower!\n");
1382 return (object *) NULL; 1526 return (object *) NULL;
1383 } 1527 }
1384 1528
1385 /* prefer marked item */ 1529 /* prefer marked item */
1386 tmp = find_marked_object(op); 1530 tmp = find_marked_object (op);
1387 if (tmp != NULL) { 1531 if (tmp != NULL)
1532 {
1388 /* can't toss invisible or inv-locked items */ 1533 /* can't toss invisible or inv-locked items */
1389 if (tmp->invisible || QUERY_FLAG(tmp, FLAG_INV_LOCKED)) { 1534 if (tmp->invisible || QUERY_FLAG (tmp, FLAG_INV_LOCKED))
1535 {
1390 tmp = NULL; 1536 tmp = NULL;
1391 } 1537 }
1392 } 1538 }
1393 1539
1394 /* look through the inventory */ 1540 /* look through the inventory */
1395 if (tmp == NULL) { 1541 if (tmp == NULL)
1542 {
1396 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) { 1543 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1544 {
1397 /* can't toss invisible or inv-locked items */ 1545 /* can't toss invisible or inv-locked items */
1398 if (tmp->invisible || QUERY_FLAG(tmp, FLAG_INV_LOCKED)) 1546 if (tmp->invisible || QUERY_FLAG (tmp, FLAG_INV_LOCKED))
1399 continue; 1547 continue;
1400 if (!request 1548 if (!request || !strcmp (query_name (tmp), request) || !strcmp (tmp->name, request))
1401 || !strcmp(query_name(tmp), request)
1402 || !strcmp(tmp->name, request))
1403 break; 1549 break;
1404 } 1550 }
1405 } 1551 }
1406 1552
1407 /* this should prevent us from throwing away 1553 /* this should prevent us from throwing away
1408 * cursed items, worn armour, etc. Only weapons 1554 * cursed items, worn armour, etc. Only weapons
1409 * can be thrown from 'hand'. 1555 * can be thrown from 'hand'.
1410 */ 1556 */
1557 if (!tmp)
1411 if (!tmp) return NULL; 1558 return NULL;
1412 1559
1413 if (QUERY_FLAG(tmp,FLAG_APPLIED)) { 1560 if (QUERY_FLAG (tmp, FLAG_APPLIED))
1561 {
1414 if(tmp->type!=WEAPON) { 1562 if (tmp->type != WEAPON)
1415 new_draw_info_format(NDI_UNIQUE, 0,op, 1563 {
1416 "You can't throw %s.",query_name(tmp)); 1564 new_draw_info_format (NDI_UNIQUE, 0, op, "You can't throw %s.", query_name (tmp));
1417 tmp = NULL; 1565 tmp = NULL;
1566 }
1418 } else if (QUERY_FLAG(tmp,FLAG_CURSED)||QUERY_FLAG(tmp,FLAG_DAMNED)) { 1567 else if (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))
1419 new_draw_info_format(NDI_UNIQUE, 0,op, 1568 {
1420 "The %s sticks to your hand!",query_name(tmp)); 1569 new_draw_info_format (NDI_UNIQUE, 0, op, "The %s sticks to your hand!", query_name (tmp));
1421 tmp = NULL; 1570 tmp = NULL;
1422 } else { 1571 }
1572 else
1573 {
1423 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE)) { 1574 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
1575 {
1424 LOG (llevError, "BUG: find_throw_ob(): couldn't unapply\n"); 1576 LOG (llevError, "BUG: find_throw_ob(): couldn't unapply\n");
1425 tmp = NULL; 1577 tmp = NULL;
1578 }
1579 }
1426 } 1580 }
1427 }
1428 } else if (QUERY_FLAG(tmp, FLAG_UNPAID)) { 1581 else if (QUERY_FLAG (tmp, FLAG_UNPAID))
1582 {
1429 new_draw_info_format(NDI_UNIQUE, 0, op, "You should pay for the %s first.", query_name(tmp)); 1583 new_draw_info_format (NDI_UNIQUE, 0, op, "You should pay for the %s first.", query_name (tmp));
1430 tmp = NULL; 1584 tmp = NULL;
1431 } 1585 }
1432 1586
1433 if (tmp && QUERY_FLAG (tmp, FLAG_INV_LOCKED)) { 1587 if (tmp && QUERY_FLAG (tmp, FLAG_INV_LOCKED))
1588 {
1434 LOG (llevError, "BUG: find_throw_ob(): object is locked\n"); 1589 LOG (llevError, "BUG: find_throw_ob(): object is locked\n");
1435 tmp=NULL; 1590 tmp = NULL;
1436 } 1591 }
1437 return tmp; 1592 return tmp;
1438} 1593}
1439 1594
1440/* make_throw_ob() We construct the 'carrier' object in 1595/* make_throw_ob() We construct the 'carrier' object in
1441 * which we will insert the object that is being thrown. 1596 * which we will insert the object that is being thrown.
1442 * This combination becomes the 'thrown object'. -b.t. 1597 * This combination becomes the 'thrown object'. -b.t.
1443 */ 1598 */
1444 1599
1600static object *
1445static object *make_throw_ob (object *orig) { 1601make_throw_ob (object *orig)
1602{
1446 object *toss_item; 1603 object *toss_item;
1447 1604
1605 if (!orig)
1448 if(!orig) return NULL; 1606 return NULL;
1449 1607
1450 toss_item=get_object(); 1608 toss_item = get_object ();
1451 if (QUERY_FLAG (orig, FLAG_APPLIED)) { 1609 if (QUERY_FLAG (orig, FLAG_APPLIED))
1610 {
1452 LOG (llevError, "BUG: make_throw_ob(): ob is applied\n"); 1611 LOG (llevError, "BUG: make_throw_ob(): ob is applied\n");
1453 /* insufficient workaround, but better than nothing */ 1612 /* insufficient workaround, but better than nothing */
1454 CLEAR_FLAG (orig, FLAG_APPLIED); 1613 CLEAR_FLAG (orig, FLAG_APPLIED);
1455 } 1614 }
1456 copy_object(orig,toss_item); 1615 copy_object (orig, toss_item);
1457 toss_item->type = THROWN_OBJ; 1616 toss_item->type = THROWN_OBJ;
1458 CLEAR_FLAG(toss_item,FLAG_CHANGING); 1617 CLEAR_FLAG (toss_item, FLAG_CHANGING);
1459 toss_item->stats.dam = 0; /* default damage */ 1618 toss_item->stats.dam = 0; /* default damage */
1460 insert_ob_in_ob(orig,toss_item); 1619 insert_ob_in_ob (orig, toss_item);
1461 return toss_item; 1620 return toss_item;
1462} 1621}
1463 1622
1464 1623
1465/* do_throw() - op throws any object toss_item. This code 1624/* do_throw() - op throws any object toss_item. This code
1466 * was borrowed from fire_bow. 1625 * was borrowed from fire_bow.
1467 * Returns 1 if skill was successfully used, 0 if not 1626 * Returns 1 if skill was successfully used, 0 if not
1468 */ 1627 */
1469 1628
1629static int
1470static int do_throw(object *op, object *part, object *toss_item, int dir, object *skill) { 1630do_throw (object *op, object *part, object *toss_item, int dir, object *skill)
1631{
1471 object *throw_ob=toss_item, *left=NULL; 1632 object *throw_ob = toss_item, *left = NULL;
1472 tag_t left_tag;
1473 int eff_str = 0,maxc,str=op->stats.Str,dam=0; 1633 int eff_str = 0, maxc, str = op->stats.Str, dam = 0;
1474 int pause_f,weight_f=0, mflags; 1634 int pause_f, weight_f = 0, mflags;
1475 float str_factor=1.0,load_factor=1.0,item_factor=1.0; 1635 float str_factor = 1.0, load_factor = 1.0, item_factor = 1.0;
1476 mapstruct *m; 1636 maptile *m;
1477 sint16 sx, sy; 1637 sint16 sx, sy;
1478 tag_t tag;
1479 1638
1480 if(throw_ob==NULL) { 1639 if (throw_ob == NULL)
1640 {
1481 if(op->type==PLAYER) { 1641 if (op->type == PLAYER)
1482 new_draw_info(NDI_UNIQUE, 0,op,"You have nothing to throw."); 1642 new_draw_info (NDI_UNIQUE, 0, op, "You have nothing to throw.");
1483 } 1643
1484 return 0; 1644 return 0;
1485 } 1645 }
1486 if (QUERY_FLAG(throw_ob, FLAG_STARTEQUIP)) { 1646 if (QUERY_FLAG (throw_ob, FLAG_STARTEQUIP))
1647 {
1487 if (op->type==PLAYER) { 1648 if (op->type == PLAYER)
1488 new_draw_info(NDI_UNIQUE, 0, op, "The gods won't let you throw that."); 1649 new_draw_info (NDI_UNIQUE, 0, op, "The gods won't let you throw that.");
1489 }
1490 return 0;
1491 }
1492 1650
1651 return 0;
1652 }
1653
1493 /* Because throwing effectiveness must be reduced by the 1654 /* Because throwing effectiveness must be reduced by the
1494 * encumbrance of the thrower and weight of the object. THus, 1655 * encumbrance of the thrower and weight of the object. THus,
1495 * we use the concept of 'effective strength' as defined below. 1656 * we use the concept of 'effective strength' as defined below.
1496 */ 1657 */
1497 1658
1498 /* if str exceeds MAX_STAT (30, eg giants), lets assign a str_factor > 1 */ 1659 /* if str exceeds MAX_STAT (30, eg giants), lets assign a str_factor > 1 */
1499 if(str>MAX_STAT) { 1660 if (str > MAX_STAT)
1500 str_factor = (float) str /(float) MAX_STAT; str = MAX_STAT;
1501 } 1661 {
1662 str_factor = (float) str / (float) MAX_STAT;
1663 str = MAX_STAT;
1502 1664 }
1665
1503 /* the more we carry, the less we can throw. Limit only on players */ 1666 /* the more we carry, the less we can throw. Limit only on players */
1504 maxc=max_carry[str]*1000; 1667 maxc = max_carry[str] * 1000;
1505 if(op->carrying>maxc&&op->type==PLAYER) 1668 if (op->carrying > maxc && op->type == PLAYER)
1506 load_factor = (float)maxc/(float) op->carrying; 1669 load_factor = (float) maxc / (float) op->carrying;
1507 1670
1508 /* lighter items are thrown harder, farther, faster */ 1671 /* lighter items are thrown harder, farther, faster */
1509 if(throw_ob->weight>0) 1672 if (throw_ob->weight > 0)
1510 item_factor = (float) maxc/(float) (3.0 * throw_ob->weight); 1673 item_factor = (float) maxc / (float) (3.0 * throw_ob->weight);
1674 else
1511 else { /* 0 or negative weight?!? Odd object, can't throw it */ 1675 { /* 0 or negative weight?!? Odd object, can't throw it */
1512 new_draw_info_format(NDI_UNIQUE, 0,op,"You can't throw %s.\n", 1676 new_draw_info_format (NDI_UNIQUE, 0, op, "You can't throw %s.\n", query_name (throw_ob));
1513 query_name(throw_ob)); 1677 return 0;
1514 return 0;
1515 }
1516 1678 }
1679
1517 eff_str = (int) (str * (load_factor<1.0?load_factor:1.0)); 1680 eff_str = (int) (str * (load_factor < 1.0 ? load_factor : 1.0));
1518 eff_str = (int) ((float) eff_str * item_factor * str_factor); 1681 eff_str = (int) ((float) eff_str * item_factor * str_factor);
1519 1682
1520 /* alas, arrays limit us to a value of MAX_STAT (30). Use str_factor to 1683 /* alas, arrays limit us to a value of MAX_STAT (30). Use str_factor to
1521 * account for super-strong throwers. */ 1684 * account for super-strong throwers. */
1522 if(eff_str>MAX_STAT) eff_str=MAX_STAT; 1685 if (eff_str > MAX_STAT)
1686 eff_str = MAX_STAT;
1523 1687
1524#ifdef DEBUG_THROW 1688#ifdef DEBUG_THROW
1525 LOG(llevDebug,"%s carries %d, eff_str=%d\n",op->name,op->carrying,eff_str); 1689 LOG (llevDebug, "%s carries %d, eff_str=%d\n", op->name, op->carrying, eff_str);
1526 LOG(llevDebug," max_c=%d, item_f=%f, load_f=%f, str=%d\n",maxc, 1690 LOG (llevDebug, " max_c=%d, item_f=%f, load_f=%f, str=%d\n", maxc, item_factor, load_factor, op->stats.Str);
1527 item_factor,load_factor,op->stats.Str);
1528 LOG(llevDebug," str_factor=%f\n",str_factor); 1691 LOG (llevDebug, " str_factor=%f\n", str_factor);
1529 LOG(llevDebug," item %s weight= %d\n",throw_ob->name,throw_ob->weight); 1692 LOG (llevDebug, " item %s weight= %d\n", throw_ob->name, throw_ob->weight);
1530#endif 1693#endif
1531 1694
1532 /* 3 things here prevent a throw, you aimed at your feet, you 1695 /* 3 things here prevent a throw, you aimed at your feet, you
1533 * have no effective throwing strength, or you threw at something 1696 * have no effective throwing strength, or you threw at something
1534 * that flying objects can't get through. 1697 * that flying objects can't get through.
1535 */ 1698 */
1536 mflags = get_map_flags(part->map,&m, part->x+freearr_x[dir],part->y+freearr_y[dir],&sx,&sy); 1699 mflags = get_map_flags (part->map, &m, part->x + freearr_x[dir], part->y + freearr_y[dir], &sx, &sy);
1537 1700
1538 if(!dir || (eff_str <= 1) || (mflags & P_OUT_OF_MAP) || 1701 if (!dir || (eff_str <= 1) || (mflags & P_OUT_OF_MAP) || (GET_MAP_MOVE_BLOCK (m, sx, sy) & MOVE_FLY_LOW))
1539 (GET_MAP_MOVE_BLOCK(m, sx, sy) & MOVE_FLY_LOW)) { 1702 {
1540 1703
1541 /* bounces off 'wall', and drops to feet */ 1704 /* bounces off 'wall', and drops to feet */
1542 remove_ob(throw_ob); 1705 remove_ob (throw_ob);
1543 throw_ob->x = part->x; throw_ob->y = part->y; 1706 throw_ob->x = part->x;
1707 throw_ob->y = part->y;
1544 insert_ob_in_map(throw_ob,part->map,op,0); 1708 insert_ob_in_map (throw_ob, part->map, op, 0);
1545 if(op->type==PLAYER) { 1709 if (op->type == PLAYER)
1710 {
1546 if(eff_str<=1) { 1711 if (eff_str <= 1)
1547 new_draw_info_format(NDI_UNIQUE, 0,op, 1712 {
1548 "Your load is so heavy you drop %s to the ground.", 1713 new_draw_info_format (NDI_UNIQUE, 0, op, "Your load is so heavy you drop %s to the ground.", query_name (throw_ob));
1549 query_name(throw_ob)); 1714 }
1550 }
1551 else if(!dir) { 1715 else if (!dir)
1716 {
1552 new_draw_info_format(NDI_UNIQUE, 0,op,"You throw %s at the ground.", 1717 new_draw_info_format (NDI_UNIQUE, 0, op, "You throw %s at the ground.", query_name (throw_ob));
1553 query_name(throw_ob)); 1718 }
1554 } 1719 else
1555 else
1556 new_draw_info(NDI_UNIQUE, 0,op,"Something is in the way."); 1720 new_draw_info (NDI_UNIQUE, 0, op, "Something is in the way.");
1557 } 1721 }
1558 return 0; 1722 return 0;
1559 } /* if object can't be thrown */ 1723 } /* if object can't be thrown */
1560 1724
1561 left = throw_ob; /* these are throwing objects left to the player */ 1725 left = throw_ob; /* these are throwing objects left to the player */
1562 left_tag = left->count;
1563 1726
1564 /* sometimes get_split_ob can't split an object (because op->nrof==0?) 1727 /* sometimes get_split_ob can't split an object (because op->nrof==0?)
1565 * and returns NULL. We must use 'left' then 1728 * and returns NULL. We must use 'left' then
1566 */ 1729 */
1567 1730
1568 if((throw_ob = get_split_ob(throw_ob, 1))==NULL) { 1731 if ((throw_ob = get_split_ob (throw_ob, 1)) == NULL)
1732 {
1569 throw_ob = left; 1733 throw_ob = left;
1570 remove_ob(left); 1734 remove_ob (left);
1571 if (op->type==PLAYER) 1735 if (op->type == PLAYER)
1572 esrv_del_item(op->contr, left->count); 1736 esrv_del_item (op->contr, left->count);
1573 } 1737 }
1574 else if (op->type==PLAYER) { 1738 else if (op->type == PLAYER)
1575 if (was_destroyed (left, left_tag)) 1739 {
1740 if (left->destroyed ())
1576 esrv_del_item(op->contr, left_tag); 1741 esrv_del_item (op->contr, left->count);
1577 else 1742 else
1578 esrv_update_item(UPD_NROF, op, left); 1743 esrv_update_item (UPD_NROF, op, left);
1579 } 1744 }
1580 1745
1581 /* special case: throwing powdery substances like dust, dirt */ 1746 /* special case: throwing powdery substances like dust, dirt */
1582 if(throw_ob->type == POTION && throw_ob->subtype == POT_DUST) { 1747 if (throw_ob->type == POTION && throw_ob->subtype == POT_DUST)
1748 {
1583 cast_dust(op,throw_ob,dir); 1749 cast_dust (op, throw_ob, dir);
1584 return 1; 1750 return 1;
1585 } 1751 }
1586 1752
1587 /* Make a thrown object -- insert real object in a 'carrier' object. 1753 /* Make a thrown object -- insert real object in a 'carrier' object.
1588 * If unsuccessfull at making the "thrown_obj", we just reinsert 1754 * If unsuccessfull at making the "thrown_obj", we just reinsert
1589 * the original object back into inventory and exit 1755 * the original object back into inventory and exit
1590 */ 1756 */
1591 if((toss_item = make_throw_ob(throw_ob))) { 1757 if ((toss_item = make_throw_ob (throw_ob)))
1758 {
1592 throw_ob = toss_item; 1759 throw_ob = toss_item;
1593 if (throw_ob->skill) free_string(throw_ob->skill);
1594 throw_ob->skill = add_string(skill->skill); 1760 throw_ob->skill = skill->skill;
1761 }
1762 else
1595 } 1763 {
1596 else {
1597 insert_ob_in_ob(throw_ob,op); 1764 insert_ob_in_ob (throw_ob, op);
1598 return 0; 1765 return 0;
1599 } 1766 }
1600 1767
1601 set_owner(throw_ob,op); 1768 set_owner (throw_ob, op);
1602 /* At some point in the attack code, the actual real object (op->inv) 1769 /* At some point in the attack code, the actual real object (op->inv)
1603 * becomes the hitter. As such, we need to make sure that has a proper 1770 * becomes the hitter. As such, we need to make sure that has a proper
1604 * owner value so exp goes to the right place. 1771 * owner value so exp goes to the right place.
1605 */ 1772 */
1606 set_owner(throw_ob->inv,op); 1773 set_owner (throw_ob->inv, op);
1607 throw_ob->direction=dir; 1774 throw_ob->direction = dir;
1608 throw_ob->x = part->x; 1775 throw_ob->x = part->x;
1609 throw_ob->y = part->y; 1776 throw_ob->y = part->y;
1610 1777
1611 /* the damage bonus from the force of the throw */ 1778 /* the damage bonus from the force of the throw */
1612 dam = (int) (str_factor * dam_bonus[eff_str]); 1779 dam = (int) (str_factor * dam_bonus[eff_str]);
1613 1780
1614 /* Now, lets adjust the properties of the thrown_ob. */ 1781 /* Now, lets adjust the properties of the thrown_ob. */
1615 1782
1616 /* how far to fly */ 1783 /* how far to fly */
1617 throw_ob->last_sp = (eff_str*3)/5; 1784 throw_ob->last_sp = (eff_str * 3) / 5;
1618 1785
1619 /* speed */ 1786 /* speed */
1620 throw_ob->speed = (speed_bonus[eff_str]+1.0)/1.5; 1787 throw_ob->speed = (speed_bonus[eff_str] + 1.0) / 1.5;
1621 throw_ob->speed = MIN(1.0,throw_ob->speed); /* no faster than an arrow! */ 1788 throw_ob->speed = MIN (1.0, throw_ob->speed); /* no faster than an arrow! */
1622 1789
1623 /* item damage. Eff_str and item weight influence damage done */ 1790 /* item damage. Eff_str and item weight influence damage done */
1624 weight_f = (throw_ob->weight/2000)>MAX_STAT?MAX_STAT:(throw_ob->weight/2000); 1791 weight_f = (throw_ob->weight / 2000) > MAX_STAT ? MAX_STAT : (throw_ob->weight / 2000);
1625 throw_ob->stats.dam += (dam/3) + dam_bonus[weight_f] 1792 throw_ob->stats.dam += (dam / 3) + dam_bonus[weight_f] + (throw_ob->weight / 15000) - 2;
1626 + (throw_ob->weight/15000) - 2;
1627 1793
1628 /* chance of breaking. Proportional to force used and weight of item */ 1794 /* chance of breaking. Proportional to force used and weight of item */
1629 throw_ob->stats.food = (dam/2) + (throw_ob->weight/60000); 1795 throw_ob->stats.food = (dam / 2) + (throw_ob->weight / 60000);
1630 1796
1631 /* replace 25 with a call to clone.arch wc? messes up w/ NPC */ 1797 /* replace 25 with a call to clone.arch wc? messes up w/ NPC */
1632 throw_ob->stats.wc = 25 - dex_bonus[op->stats.Dex] 1798 throw_ob->stats.wc = 25 - dex_bonus[op->stats.Dex] - thaco_bonus[eff_str] - skill->level;
1633 - thaco_bonus[eff_str] - skill->level;
1634
1635 1799
1800
1636 /* the properties of objects which are meant to be thrown (ie dart, 1801 /* the properties of objects which are meant to be thrown (ie dart,
1637 * throwing knife, etc) will differ from ordinary items. Lets tailor 1802 * throwing knife, etc) will differ from ordinary items. Lets tailor
1638 * this stuff in here. 1803 * this stuff in here.
1639 */ 1804 */
1640 1805
1641 if(QUERY_FLAG(throw_ob->inv,FLAG_IS_THROWN)) { 1806 if (QUERY_FLAG (throw_ob->inv, FLAG_IS_THROWN))
1807 {
1642 throw_ob->last_sp += eff_str/3; /* fly a little further */ 1808 throw_ob->last_sp += eff_str / 3; /* fly a little further */
1643 throw_ob->stats.dam += throw_ob->inv->stats.dam + throw_ob->magic + 2; 1809 throw_ob->stats.dam += throw_ob->inv->stats.dam + throw_ob->magic + 2;
1644 throw_ob->stats.wc -= throw_ob->magic + throw_ob->inv->stats.wc; 1810 throw_ob->stats.wc -= throw_ob->magic + throw_ob->inv->stats.wc;
1645 /* only throw objects get directional faces */ 1811 /* only throw objects get directional faces */
1646 if(GET_ANIM_ID(throw_ob) && NUM_ANIMATIONS(throw_ob)) 1812 if (GET_ANIM_ID (throw_ob) && NUM_ANIMATIONS (throw_ob))
1647 SET_ANIMATION(throw_ob, dir); 1813 SET_ANIMATION (throw_ob, dir);
1648 } else { 1814 }
1815 else
1816 {
1649 /* some materials will adjust properties.. */ 1817 /* some materials will adjust properties.. */
1650 if(throw_ob->material&M_LEATHER) { 1818 if (throw_ob->material & M_LEATHER)
1819 {
1651 throw_ob->stats.dam -= 1; 1820 throw_ob->stats.dam -= 1;
1652 throw_ob->stats.food -= 10; 1821 throw_ob->stats.food -= 10;
1653 } 1822 }
1654 if(throw_ob->material&M_GLASS) throw_ob->stats.food += 60; 1823 if (throw_ob->material & M_GLASS)
1655 1824 throw_ob->stats.food += 60;
1825
1656 if(throw_ob->material&M_ORGANIC) { 1826 if (throw_ob->material & M_ORGANIC)
1827 {
1657 throw_ob->stats.dam -= 3; 1828 throw_ob->stats.dam -= 3;
1658 throw_ob->stats.food += 55; 1829 throw_ob->stats.food += 55;
1659 } 1830 }
1660 if(throw_ob->material&M_PAPER||throw_ob->material&M_CLOTH) { 1831 if (throw_ob->material & M_PAPER || throw_ob->material & M_CLOTH)
1661 throw_ob->stats.dam -= 5; throw_ob->speed *= 0.8; 1832 {
1662 throw_ob->stats.wc += 3; throw_ob->stats.food -= 30; 1833 throw_ob->stats.dam -= 5;
1663 } 1834 throw_ob->speed *= 0.8;
1835 throw_ob->stats.wc += 3;
1836 throw_ob->stats.food -= 30;
1837 }
1664 /* light obj have more wind resistance, fly slower*/ 1838 /* light obj have more wind resistance, fly slower */
1665 if(throw_ob->weight>500) throw_ob->speed *= 0.8; 1839 if (throw_ob->weight > 500)
1666 if(throw_ob->weight>50) throw_ob->speed *= 0.5; 1840 throw_ob->speed *= 0.8;
1667 1841 if (throw_ob->weight > 50)
1668 } /* else tailor thrown object */ 1842 throw_ob->speed *= 0.5;
1669 1843
1844 } /* else tailor thrown object */
1845
1670 /* some limits, and safeties (needed?) */ 1846 /* some limits, and safeties (needed?) */
1671 if(throw_ob->stats.dam<0) throw_ob->stats.dam=0; 1847 if (throw_ob->stats.dam < 0)
1672 if(throw_ob->last_sp>eff_str) throw_ob->last_sp=eff_str; 1848 throw_ob->stats.dam = 0;
1673 if(throw_ob->stats.food<0) throw_ob->stats.food=0; 1849 if (throw_ob->last_sp > eff_str)
1674 if(throw_ob->stats.food>100) throw_ob->stats.food=100; 1850 throw_ob->last_sp = eff_str;
1675 if(throw_ob->stats.wc>30) throw_ob->stats.wc=30; 1851 if (throw_ob->stats.food < 0)
1852 throw_ob->stats.food = 0;
1853 if (throw_ob->stats.food > 100)
1854 throw_ob->stats.food = 100;
1855 if (throw_ob->stats.wc > 30)
1856 throw_ob->stats.wc = 30;
1676 1857
1677 /* how long to pause the thrower. Higher values mean less pause */ 1858 /* how long to pause the thrower. Higher values mean less pause */
1678 pause_f = ((2*eff_str)/3)+20+skill->level; 1859 pause_f = ((2 * eff_str) / 3) + 20 + skill->level;
1679 1860
1680 /* Put a lower limit on this */ 1861 /* Put a lower limit on this */
1681 if (pause_f < 10) pause_f=10; 1862 if (pause_f < 10)
1682 if (pause_f > 100) pause_f=100; 1863 pause_f = 10;
1864 if (pause_f > 100)
1865 pause_f = 100;
1683 1866
1684 /* Changed in 0.94.2 - the calculation before was really goofy. 1867 /* Changed in 0.94.2 - the calculation before was really goofy.
1685 * In short summary, a throw can take anywhere between speed 5 and 1868 * In short summary, a throw can take anywhere between speed 5 and
1686 * speed 0.5 1869 * speed 0.5
1687 */ 1870 */
1688 op->speed_left -= 50 / pause_f; 1871 op->speed_left -= 50 / pause_f;
1689 1872
1690 update_ob_speed(throw_ob); 1873 update_ob_speed (throw_ob);
1691 throw_ob->speed_left = 0; 1874 throw_ob->speed_left = 0;
1692 throw_ob->map = part->map; 1875 throw_ob->map = part->map;
1693 1876
1694 throw_ob->move_type = MOVE_FLY_LOW; 1877 throw_ob->move_type = MOVE_FLY_LOW;
1695 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK; 1878 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK;
1696 1879
1697#if 0 1880#if 0
1698 /* need to put in a good sound for this */ 1881 /* need to put in a good sound for this */
1699 play_sound_map(op->map, op->x, op->y, SOUND_THROW_OBJ); 1882 play_sound_map (op->map, op->x, op->y, SOUND_THROW_OBJ);
1700#endif 1883#endif
1884
1701/* Lauwenmark - Now we can call the associated script_throw event (if any) */ 1885/* Lauwenmark - Now we can call the associated script_throw event (if any) */
1702 execute_event(throw_ob, EVENT_THROW,op,NULL,NULL,SCRIPT_FIX_ACTIVATOR); 1886 INVOKE_OBJECT (THROW, throw_ob, ARG_OBJECT (op));
1703#ifdef DEBUG_THROW 1887#ifdef DEBUG_THROW
1704 LOG(llevDebug," pause_f=%d \n",pause_f); 1888 LOG (llevDebug, " pause_f=%d \n", pause_f);
1705 LOG(llevDebug," %s stats: wc=%d dam=%d dist=%d spd=%f break=%d\n", 1889 LOG (llevDebug, " %s stats: wc=%d dam=%d dist=%d spd=%f break=%d\n",
1706 throw_ob->name,throw_ob->stats.wc,throw_ob->stats.dam, 1890 throw_ob->name, throw_ob->stats.wc, throw_ob->stats.dam, throw_ob->last_sp, throw_ob->speed, throw_ob->stats.food);
1707 throw_ob->last_sp,throw_ob->speed,throw_ob->stats.food);
1708 LOG(llevDebug,"inserting tossitem (%d) into map\n",throw_ob->count); 1891 LOG (llevDebug, "inserting tossitem (%d) into map\n", throw_ob->count);
1709#endif 1892#endif
1710 tag = throw_ob->count;
1711 insert_ob_in_map(throw_ob,part->map,op,0); 1893 insert_ob_in_map (throw_ob, part->map, op, 0);
1712 if (!was_destroyed (throw_ob, tag)) 1894
1895 if (!throw_ob->destroyed ())
1713 move_arrow(throw_ob); 1896 move_arrow (throw_ob);
1897
1714 return 1; 1898 return 1;
1715} 1899}
1716 1900
1901int
1717int skill_throw (object *op, object *part, int dir, const char *params, object *skill) { 1902skill_throw (object *op, object *part, int dir, const char *params, object *skill)
1903{
1718 object *throw_ob; 1904 object *throw_ob;
1719 1905
1720 if(op->type==PLAYER) 1906 if (op->type == PLAYER)
1721 throw_ob = find_throw_ob(op,params); 1907 throw_ob = find_throw_ob (op, params);
1722 else 1908 else
1723 throw_ob = find_mon_throw_ob(op); 1909 throw_ob = find_mon_throw_ob (op);
1724 1910
1725 return do_throw(op,part, throw_ob,dir, skill); 1911 return do_throw (op, part, throw_ob, dir, skill);
1726} 1912}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines