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.3 by root, Thu Aug 17 20:23:31 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.3 2006/08/17 20:23:31 root 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 stop_jump(pl,i,spaces); 569 pl->map = m;
570 stop_jump (pl, i, spaces);
508 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;
509 } 577 }
510 }
511 pl->x = x;
512 pl->y = y;
513 pl->map = m;
514 }
515 stop_jump(pl,i,spaces); 578 stop_jump (pl, i, spaces);
516 return calc_skill_exp(pl,NULL, skill); 579 return calc_skill_exp (pl, NULL, skill);
517} 580}
518 581
519/* 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
520 * an attack as well. 583 * an attack as well.
521 * 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
522 * jumper can jump several spaces? 585 * jumper can jump several spaces?
523 */ 586 */
524 587
588int
525int jump(object *pl, int dir, object *skill) 589jump (object *pl, int dir, object *skill)
526{ 590{
527 int spaces=0,stats; 591 int spaces = 0, stats;
528 int str = pl->stats.Str; 592 int str = pl->stats.Str;
529 int dex = pl->stats.Dex; 593 int dex = pl->stats.Dex;
530 594
531 dex = dex ? dex : 15; 595 dex = dex ? dex : 15;
532 str = str ? str : 10; 596 str = str ? str : 10;
533 597
534 stats=str*str*str*dex * skill->level; 598 stats = str * str * str * dex * skill->level;
535 599
536 if(pl->carrying!=0) /* don't want div by zero !! */ 600 if (pl->carrying != 0) /* don't want div by zero !! */
537 spaces=(int) (stats/pl->carrying); 601 spaces = (int) (stats / pl->carrying);
538 else 602 else
539 spaces=2; /* pl has no objects - gets the far jump */ 603 spaces = 2; /* pl has no objects - gets the far jump */
540 604
541 if(spaces>2) 605 if (spaces > 2)
542 spaces = 2; 606 spaces = 2;
543 else if(spaces==0) { 607 else if (spaces == 0)
608 {
544 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.");
545 return 0; 610 return 0;
546 } 611 }
547 return attempt_jump(pl,dir,spaces, skill); 612 return attempt_jump (pl, dir, spaces, skill);
548} 613}
549 614
550 615
551/* skill_ident() - this code is supposed to allow players to identify 616/* skill_ident() - this code is supposed to allow players to identify
552 * classes of objects with the various "auto-ident" skills. Player must 617 * classes of objects with the various "auto-ident" skills. Player must
556 * more generalized. Right now, skill indices are embedded in this routine. 621 * more generalized. Right now, skill indices are embedded in this routine.
557 * Returns amount of experience gained (on successful ident). 622 * Returns amount of experience gained (on successful ident).
558 * - b.t. (thomas@astro.psu.edu) 623 * - b.t. (thomas@astro.psu.edu)
559 */ 624 */
560 625
626static int
561static int do_skill_detect_curse(object *pl, object *skill) { 627do_skill_detect_curse (object *pl, object *skill)
628{
562 object *tmp; 629 object *tmp;
563 int success=0; 630 int success = 0;
564 631
565 for(tmp=pl->inv;tmp;tmp=tmp->below) 632 for (tmp = pl->inv; tmp; tmp = tmp->below)
566 if (!tmp->invisible 633 if (!tmp->invisible
567 && !QUERY_FLAG(tmp,FLAG_IDENTIFIED) && !QUERY_FLAG(tmp,FLAG_KNOWN_CURSED) 634 && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)
568 && (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)
569 tmp->item_power < skill->level) { 636 {
570 SET_FLAG(tmp,FLAG_KNOWN_CURSED); 637 SET_FLAG (tmp, FLAG_KNOWN_CURSED);
571 esrv_update_item(UPD_FLAGS, pl, tmp); 638 esrv_update_item (UPD_FLAGS, pl, tmp);
572 success+= calc_skill_exp(pl,tmp, skill); 639 success += calc_skill_exp (pl, tmp, skill);
573 } 640 }
574 641
575 /* Check ground, too, but only objects the player could pick up */ 642 /* Check ground, too, but only objects the player could pick up */
576 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)
577 if (can_pick(pl, tmp) && 644 if (can_pick (pl, tmp) &&
578 !QUERY_FLAG(tmp,FLAG_IDENTIFIED) && 645 !QUERY_FLAG (tmp, FLAG_IDENTIFIED) &&
579 !QUERY_FLAG(tmp,FLAG_KNOWN_CURSED) 646 !QUERY_FLAG (tmp, FLAG_KNOWN_CURSED)
580 && (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)
581 tmp->item_power < skill->level) { 648 {
582 SET_FLAG(tmp,FLAG_KNOWN_CURSED); 649 SET_FLAG (tmp, FLAG_KNOWN_CURSED);
583 esrv_update_item(UPD_FLAGS, pl, tmp); 650 esrv_update_item (UPD_FLAGS, pl, tmp);
584 success+= calc_skill_exp(pl,tmp, skill); 651 success += calc_skill_exp (pl, tmp, skill);
585 } 652 }
586 653
587 return success; 654 return success;
588} 655}
589 656
657static int
590static int do_skill_detect_magic(object *pl, object *skill) { 658do_skill_detect_magic (object *pl, object *skill)
659{
591 object *tmp; 660 object *tmp;
592 int success=0; 661 int success = 0;
593 662
594 for(tmp=pl->inv;tmp;tmp=tmp->below) 663 for (tmp = pl->inv; tmp; tmp = tmp->below)
595 if(!tmp->invisible 664 if (!tmp->invisible
596 && !QUERY_FLAG(tmp,FLAG_IDENTIFIED) && !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) 665 && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && !QUERY_FLAG (tmp, FLAG_KNOWN_MAGICAL)
597 && (is_magical(tmp)) && tmp->item_power < skill->level) { 666 && (is_magical (tmp)) && tmp->item_power < skill->level)
667 {
598 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 668 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
599 esrv_update_item(UPD_FLAGS, pl, tmp); 669 esrv_update_item (UPD_FLAGS, pl, tmp);
600 success+=calc_skill_exp(pl,tmp, skill); 670 success += calc_skill_exp (pl, tmp, skill);
601 } 671 }
602 672
603 /* 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 */
604 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)
605 if (can_pick(pl, tmp) && 675 if (can_pick (pl, tmp) &&
606 !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)
607 !QUERY_FLAG(tmp,FLAG_KNOWN_MAGICAL) 677 {
608 && (is_magical(tmp)) && tmp->item_power < skill->level) {
609 SET_FLAG(tmp,FLAG_KNOWN_MAGICAL); 678 SET_FLAG (tmp, FLAG_KNOWN_MAGICAL);
610 esrv_update_item(UPD_FLAGS, pl, tmp); 679 esrv_update_item (UPD_FLAGS, pl, tmp);
611 success+=calc_skill_exp(pl,tmp, skill); 680 success += calc_skill_exp (pl, tmp, skill);
612 } 681 }
613 682
614 return success; 683 return success;
615} 684}
616 685
617/* Helper function for do_skill_ident, so that we can loop 686/* Helper function for do_skill_ident, so that we can loop
618 * over inventory AND objects on the ground conveniently. 687 * over inventory AND objects on the ground conveniently.
619 */ 688 */
689int
620int do_skill_ident2(object *tmp,object *pl, int obj_class, object *skill) 690do_skill_ident2 (object *tmp, object *pl, int obj_class, object *skill)
621{ 691{
622 int success = 0, chance; 692 int success = 0, chance;
623 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;
624 694
625 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)
626 && need_identify (tmp) && !tmp->invisible && tmp->type == obj_class) 696 && need_identify (tmp) && !tmp->invisible && tmp->type == obj_class)
627 { 697 {
628 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);
629 + rndm (0, (tmp->magic ? tmp->magic * 5 : 1) - 1);
630 699
631 if (skill_value >= chance) 700 if (skill_value >= chance)
632 { 701 {
633 identify(tmp); 702 identify (tmp);
634 703
635 if (pl->type==PLAYER) 704 if (pl->type == PLAYER)
636 { 705 {
637 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));
638 707
639 if (tmp->msg) 708 if (tmp->msg)
640 { 709 {
641 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:");
642 new_draw_info(NDI_UNIQUE, 0,pl, tmp->msg); 711 new_draw_info (NDI_UNIQUE, 0, pl, tmp->msg);
643 } 712 }
644 713
645 /* 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 */
646 if (tmp->map) 715 if (tmp->map)
647 esrv_send_item (pl, tmp); 716 esrv_send_item (pl, tmp);
648 } 717 }
649 success += calc_skill_exp(pl,tmp, skill); 718 success += calc_skill_exp (pl, tmp, skill);
650 } 719 }
651 else 720 else
652 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT); 721 SET_FLAG (tmp, FLAG_NO_SKILL_IDENT);
653 } 722 }
654 723
655 return success; 724 return success;
656} 725}
657 726
658/* do_skill_ident() - workhorse for skill_ident() -b.t. 727/* do_skill_ident() - workhorse for skill_ident() -b.t.
659 */ 728 */
729static int
660static int do_skill_ident(object *pl, int obj_class, object *skill) { 730do_skill_ident (object *pl, int obj_class, object *skill)
731{
661 object *tmp; 732 object *tmp;
662 int success=0; 733 int success = 0;
663 734
664 for(tmp=pl->inv;tmp;tmp=tmp->below) 735 for (tmp = pl->inv; tmp; tmp = tmp->below)
665 success+=do_skill_ident2(tmp,pl,obj_class, skill); 736 success += do_skill_ident2 (tmp, pl, obj_class, skill);
666 /* check the ground */ 737 /* check the ground */
667 738
668 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)
669 success+=do_skill_ident2(tmp,pl,obj_class, skill); 740 success += do_skill_ident2 (tmp, pl, obj_class, skill);
670 741
671 return success; 742 return success;
672} 743}
673 744
745int
674int skill_ident(object *pl, object *skill) { 746skill_ident (object *pl, object *skill)
747{
675 int success=0; 748 int success = 0;
676 749
677 if(pl->type != PLAYER) return 0; /* only players will skill-identify */ 750 if (pl->type != PLAYER)
751 return 0; /* only players will skill-identify */
678 752
679 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...");
680 754
681 switch (skill->subtype) { 755 switch (skill->subtype)
756 {
682 case SK_SMITHERY: 757 case SK_SMITHERY:
683 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)
684 + 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)
685 + 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)
686 + 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);
687 + do_skill_ident(pl,GLOVES,skill); 762 break;
688 break;
689 763
690 case SK_BOWYER: 764 case SK_BOWYER:
691 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);
692 break; 766 break;
693 767
694 case SK_ALCHEMY: 768 case SK_ALCHEMY:
695 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)
696 + 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);
697 + do_skill_ident(pl,DRINK,skill) + do_skill_ident(pl,INORGANIC,skill); 771 break;
698 break;
699 772
700 case SK_WOODSMAN: 773 case SK_WOODSMAN:
701 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);
702 + do_skill_ident(pl,FLESH,skill); 775 break;
703 break;
704 776
705 case SK_JEWELER: 777 case SK_JEWELER:
706 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);
707 do_skill_ident(pl,AMULET,skill); 779 break;
708 break;
709 780
710 case SK_LITERACY: 781 case SK_LITERACY:
711 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);
712 + do_skill_ident(pl,SCROLL,skill) + do_skill_ident(pl,BOOK,skill); 783 break;
713 break;
714 784
715 case SK_THAUMATURGY: 785 case SK_THAUMATURGY:
716 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);
717 + do_skill_ident(pl,HORN,skill); 787 break;
718 break;
719 788
720 case SK_DET_CURSE: 789 case SK_DET_CURSE:
721 success = do_skill_detect_curse(pl,skill); 790 success = do_skill_detect_curse (pl, skill);
722 if(success) 791 if (success)
723 new_draw_info(NDI_UNIQUE, 0,pl,"...and discover cursed items!"); 792 new_draw_info (NDI_UNIQUE, 0, pl, "...and discover cursed items!");
724 break; 793 break;
725 794
726 case SK_DET_MAGIC: 795 case SK_DET_MAGIC:
727 success = do_skill_detect_magic(pl,skill); 796 success = do_skill_detect_magic (pl, skill);
728 if(success) 797 if (success)
729 new_draw_info(NDI_UNIQUE, 0,pl, 798 new_draw_info (NDI_UNIQUE, 0, pl, "...and discover items imbued with mystic forces!");
730 "...and discover items imbued with mystic forces!"); 799 break;
731 break;
732 800
733 default: 801 default:
734 LOG(llevError,"Error: bad call to skill_ident()\n"); 802 LOG (llevError, "Error: bad call to skill_ident()\n");
735 return 0; 803 return 0;
736 break; 804 break;
737 } 805 }
738 if(!success) { 806 if (!success)
807 {
739 new_draw_info(NDI_UNIQUE, 0,pl,"...and learn nothing more."); 808 new_draw_info (NDI_UNIQUE, 0, pl, "...and learn nothing more.");
740 } 809 }
741 return success; 810 return success;
742} 811}
743 812
744 813
745/* players using this skill can 'charm' a monster -- 814/* players using this skill can 'charm' a monster --
746 * into working for them. It can only be used on 815 * into working for them. It can only be used on
747 * non-special (see below) 'neutral' creatures. 816 * non-special (see below) 'neutral' creatures.
748 * -b.t. (thomas@astro.psu.edu) 817 * -b.t. (thomas@astro.psu.edu)
749 */ 818 */
750 819
820int
751int use_oratory(object *pl, int dir, object *skill) { 821use_oratory (object *pl, int dir, object *skill)
822{
752 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];
753 int mflags,chance; 824 int mflags, chance;
754 object *tmp; 825 object *tmp;
755 mapstruct *m; 826 maptile *m;
756 827
757 if(pl->type!=PLAYER) return 0; /* only players use this skill */ 828 if (pl->type != PLAYER)
829 return 0; /* only players use this skill */
758 m = pl->map; 830 m = pl->map;
759 mflags =get_map_flags(m, &m, x,y, &x, &y); 831 mflags = get_map_flags (m, &m, x, y, &x, &y);
760 if (mflags & P_OUT_OF_MAP) return 0; 832 if (mflags & P_OUT_OF_MAP)
833 return 0;
761 834
762 /* Save some processing - we have the flag already anyways 835 /* Save some processing - we have the flag already anyways
763 */ 836 */
764 if (!(mflags & P_IS_ALIVE)) { 837 if (!(mflags & P_IS_ALIVE))
838 {
765 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.");
766 return 0; 840 return 0;
767 } 841 }
768 842
769 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 {
770 /* can't persuade players - return because there is nothing else 845 /* can't persuade players - return because there is nothing else
771 * on that space to charm. Same for multi space monsters and 846 * on that space to charm. Same for multi space monsters and
772 * 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
773 * 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
774 * only monster on the space. 849 * only monster on the space.
775 */ 850 */
776 if(tmp->type==PLAYER) return 0; 851 if (tmp->type == PLAYER)
852 return 0;
777 if(tmp->more || tmp->head) return 0; 853 if (tmp->more || tmp->head)
778 if(tmp->msg) return 0; 854 return 0;
855 if (tmp->msg)
856 return 0;
779 857
780 if(QUERY_FLAG(tmp,FLAG_MONSTER)) break; 858 if (QUERY_FLAG (tmp, FLAG_MONSTER))
859 break;
781 } 860 }
782 861
783 if (!tmp) { 862 if (!tmp)
863 {
784 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.");
785 return 0; 865 return 0;
786 } 866 }
787 867
788 new_draw_info_format(NDI_UNIQUE, 868 new_draw_info_format (NDI_UNIQUE, 0, pl, "You orate to the %s.", query_name (tmp));
789 0,pl, "You orate to the %s.",query_name(tmp));
790 869
791 /* the following conditions limit who may be 'charmed' */ 870 /* the following conditions limit who may be 'charmed' */
792 871
793 /* it's hostile! */ 872 /* it's hostile! */
794 if(!QUERY_FLAG(tmp,FLAG_UNAGGRESSIVE) && !QUERY_FLAG(tmp, FLAG_FRIENDLY)) { 873 if (!QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && !QUERY_FLAG (tmp, FLAG_FRIENDLY))
795 new_draw_info_format(NDI_UNIQUE, 0,pl,
796 "Too bad the %s isn't listening!\n",query_name(tmp));
797 return 0;
798 } 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 }
799 878
800 /* it's already allied! */ 879 /* it's already allied! */
801 if(QUERY_FLAG(tmp,FLAG_FRIENDLY)&&(tmp->attack_movement==PETMOVE)){ 880 if (QUERY_FLAG (tmp, FLAG_FRIENDLY) && (tmp->attack_movement == PETMOVE))
881 {
802 if(get_owner(tmp)==pl) { 882 if (get_owner (tmp) == pl)
803 new_draw_info(NDI_UNIQUE, 0,pl, 883 {
804 "Your follower loves your speech.\n"); 884 new_draw_info (NDI_UNIQUE, 0, pl, "Your follower loves your speech.\n");
805 return 0; 885 return 0;
886 }
806 } else if (skill->level > tmp->level) { 887 else if (skill->level > tmp->level)
888 {
807 /* you steal the follower. Perhaps we should really look at the 889 /* you steal the follower. Perhaps we should really look at the
808 * level of the owner above? 890 * level of the owner above?
809 */ 891 */
810 set_owner(tmp,pl); 892 set_owner (tmp, pl);
811 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));
812 "You convince the %s to follow you instead!\n",
813 query_name(tmp));
814 /* Abuse fix - don't give exp since this can otherwise 894 /* Abuse fix - don't give exp since this can otherwise
815 * be used by a couple players to gets lots of exp. 895 * be used by a couple players to gets lots of exp.
816 */ 896 */
817 return 0; 897 return 0;
818 } else { 898 }
899 else
900 {
819 /* 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 */
820 return 0; 902 return 0;
821 } 903 }
822 } /* Creature was already a pet of someone */ 904 } /* Creature was already a pet of someone */
823 905
824 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;
825 907
826 /* Ok, got a 'sucker' lets try to make them a follower */ 908 /* Ok, got a 'sucker' lets try to make them a follower */
827 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))
828 new_draw_info_format(NDI_UNIQUE, 0,pl, 910 {
829 "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));
830 query_name(tmp));
831 912
832 set_owner(tmp,pl); 913 set_owner (tmp, pl);
833 tmp->stats.exp = 0; 914 tmp->stats.exp = 0;
834 add_friendly_object(tmp); 915 add_friendly_object (tmp);
835 SET_FLAG(tmp,FLAG_FRIENDLY); 916 SET_FLAG (tmp, FLAG_FRIENDLY);
836 tmp->attack_movement = PETMOVE; 917 tmp->attack_movement = PETMOVE;
837 return calc_skill_exp(pl,tmp, skill); 918 return calc_skill_exp (pl, tmp, skill);
838 } 919 }
839 /* Charm failed. Creature may be angry now */ 920 /* Charm failed. Creature may be angry now */
840 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))
841 new_draw_info_format(NDI_UNIQUE, 0,pl, 922 {
842 "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));
843 if(QUERY_FLAG(tmp,FLAG_FRIENDLY)) { 924 if (QUERY_FLAG (tmp, FLAG_FRIENDLY))
925 {
844 CLEAR_FLAG(tmp,FLAG_FRIENDLY); 926 CLEAR_FLAG (tmp, FLAG_FRIENDLY);
845 remove_friendly_object(tmp); 927 remove_friendly_object (tmp);
846 tmp->attack_movement = 0; /* needed? */ 928 tmp->attack_movement = 0; /* needed? */
847 } 929 }
848 CLEAR_FLAG(tmp,FLAG_UNAGGRESSIVE); 930 CLEAR_FLAG (tmp, FLAG_UNAGGRESSIVE);
849 } 931 }
850 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 */
851} 933}
852 934
853/* Singing() -this skill allows the player to pacify nearby creatures. 935/* Singing() -this skill allows the player to pacify nearby creatures.
854 * There are few limitations on who/what kind of 936 * There are few limitations on who/what kind of
855 * non-player creatures that may be pacified. Right now, a player 937 * non-player creatures that may be pacified. Right now, a player
858 * may only pacify a creature once. 940 * may only pacify a creature once.
859 * 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
860 * of anything better! -b.t. 942 * of anything better! -b.t.
861 */ 943 */
862 944
945int
863int singing(object *pl, int dir, object *skill) { 946singing (object *pl, int dir, object *skill)
947{
864 int i,exp = 0,chance, mflags; 948 int i, exp = 0, chance, mflags;
865 object *tmp; 949 object *tmp;
866 mapstruct *m; 950 maptile *m;
867 sint16 x, y; 951 sint16 x, y;
868 952
869 if(pl->type!=PLAYER) return 0; /* only players use this skill */ 953 if (pl->type != PLAYER)
954 return 0; /* only players use this skill */
870 955
871 new_draw_info_format(NDI_UNIQUE,0,pl, "You sing."); 956 new_draw_info_format (NDI_UNIQUE, 0, pl, "You sing.");
872 for(i=0;i<MIN(skill->level,SIZEOFFREE);i++) { 957 for (i = 0; i < MIN (skill->level, SIZEOFFREE); i++)
958 {
873 x = pl->x+freearr_x[i]; 959 x = pl->x + freearr_x[i];
874 y = pl->y+freearr_y[i]; 960 y = pl->y + freearr_y[i];
875 m = pl->map; 961 m = pl->map;
876 962
877 mflags =get_map_flags(m, &m, x,y, &x, &y); 963 mflags = get_map_flags (m, &m, x, y, &x, &y);
878 if (mflags & P_OUT_OF_MAP) continue; 964 if (mflags & P_OUT_OF_MAP)
965 continue;
879 if (!(mflags & P_IS_ALIVE)) continue; 966 if (!(mflags & P_IS_ALIVE))
967 continue;
880 968
881 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 {
882 if(QUERY_FLAG(tmp,FLAG_MONSTER)) break; 971 if (QUERY_FLAG (tmp, FLAG_MONSTER))
972 break;
883 /* can't affect players */ 973 /* can't affect players */
884 if(tmp->type==PLAYER) break; 974 if (tmp->type == PLAYER)
885 } 975 break;
976 }
886 977
887 /* 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
888 * listen to singing. 979 * listen to singing.
889 */ 980 */
890 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 */
891 !QUERY_FLAG(tmp, FLAG_NO_STEAL) && /* Been charmed or abused before */
892 !QUERY_FLAG(tmp, FLAG_SPLITTING) && /* no ears */ 982 !QUERY_FLAG (tmp, FLAG_SPLITTING) && /* no ears */
893 !QUERY_FLAG(tmp, FLAG_HITBACK) && /* was here before */ 983 !QUERY_FLAG (tmp, FLAG_HITBACK) && /* was here before */
894 (tmp->level <= skill->level) && 984 (tmp->level <= skill->level) && (!tmp->head) && !QUERY_FLAG (tmp, FLAG_UNDEAD) && !QUERY_FLAG (tmp, FLAG_UNAGGRESSIVE) && /* already calm */
895 (!tmp->head) && 985 !QUERY_FLAG (tmp, FLAG_FRIENDLY))
896 !QUERY_FLAG(tmp, FLAG_UNDEAD) && 986 { /* already calm */
897 !QUERY_FLAG(tmp,FLAG_UNAGGRESSIVE) && /* already calm */
898 !QUERY_FLAG(tmp,FLAG_FRIENDLY)) { /* already calm */
899 987
900 /* stealing isn't really related (although, maybe it should 988 /* stealing isn't really related (although, maybe it should
901 * be). This is mainly to prevent singing to the same monster 989 * be). This is mainly to prevent singing to the same monster
902 * over and over again and getting exp for it. 990 * over and over again and getting exp for it.
903 */ 991 */
904 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;
905 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 {
906 SET_FLAG(tmp,FLAG_UNAGGRESSIVE); 995 SET_FLAG (tmp, FLAG_UNAGGRESSIVE);
907 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));
908 "You calm down the %s\n",query_name(tmp));
909 /* Give exp only if they are not aware */ 997 /* Give exp only if they are not aware */
910 if(!QUERY_FLAG(tmp,FLAG_NO_STEAL)) 998 if (!QUERY_FLAG (tmp, FLAG_NO_STEAL))
911 exp += calc_skill_exp(pl,tmp, skill); 999 exp += calc_skill_exp (pl, tmp, skill);
912 SET_FLAG(tmp,FLAG_NO_STEAL); 1000 SET_FLAG (tmp, FLAG_NO_STEAL);
913 } else { 1001 }
914 new_draw_info_format(NDI_UNIQUE, 0,pl, 1002 else
915 "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));
916 SET_FLAG(tmp,FLAG_NO_STEAL); 1005 SET_FLAG (tmp, FLAG_NO_STEAL);
1006 }
1007 }
917 } 1008 }
918 }
919 }
920 return exp; 1009 return exp;
921} 1010}
922 1011
923/* The find_traps skill (aka, search). Checks for traps 1012/* The find_traps skill (aka, search). Checks for traps
924 * on the spaces or in certain objects 1013 * on the spaces or in certain objects
925 */ 1014 */
926 1015
1016int
927int find_traps (object *pl, object *skill) { 1017find_traps (object *pl, object *skill)
1018{
928 object *tmp,*tmp2; 1019 object *tmp, *tmp2;
929 int i,expsum=0, mflags; 1020 int i, expsum = 0, mflags;
930 sint16 x,y; 1021 sint16 x, y;
931 mapstruct *m; 1022 maptile *m;
932 1023
933 /* 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
934 * all type RUNE 1025 * all type RUNE
935 */ 1026 */
936 1027
937 for(i=0;i<9;i++) { 1028 for (i = 0; i < 9; i++)
1029 {
938 x = pl->x+freearr_x[i]; 1030 x = pl->x + freearr_x[i];
939 y = pl->y+freearr_y[i]; 1031 y = pl->y + freearr_y[i];
940 m = pl->map; 1032 m = pl->map;
941 1033
942 mflags =get_map_flags(m, &m, x,y, &x, &y); 1034 mflags = get_map_flags (m, &m, x, y, &x, &y);
943 if (mflags & P_OUT_OF_MAP) continue; 1035 if (mflags & P_OUT_OF_MAP)
1036 continue;
944 1037
945 /* Check everything in the square for trapness */ 1038 /* Check everything in the square for trapness */
946 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 {
947 1041
948 /* And now we'd better do an inventory traversal of each 1042 /* And now we'd better do an inventory traversal of each
949 * of these objects' inventory 1043 * of these objects' inventory
950 * 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
951 * the players inventory or monsters for that matter. 1045 * the players inventory or monsters for that matter.
952 */ 1046 */
953 if (tmp->type != PLAYER && !QUERY_FLAG(tmp, FLAG_MONSTER)) { 1047 if (tmp->type != PLAYER && !QUERY_FLAG (tmp, FLAG_MONSTER))
1048 {
954 for(tmp2=tmp->inv;tmp2!=NULL;tmp2=tmp2->below) 1049 for (tmp2 = tmp->inv; tmp2 != NULL; tmp2 = tmp2->below)
955 if(tmp2->type==RUNE || tmp2->type == TRAP) 1050 if (tmp2->type == RUNE || tmp2->type == TRAP)
956 if(trap_see(pl,tmp2)) { 1051 if (trap_see (pl, tmp2))
957 trap_show(tmp2,tmp); 1052 {
958 if(tmp2->stats.Cha>1) { 1053 trap_show (tmp2, tmp);
959 if (!tmp2->owner || tmp2->owner->type!=PLAYER) 1054 if (tmp2->stats.Cha > 1)
1055 {
1056 if (!tmp2->owner || tmp2->owner->type != PLAYER)
960 expsum += calc_skill_exp(pl,tmp2, skill); 1057 expsum += calc_skill_exp (pl, tmp2, skill);
961 1058
962 tmp2->stats.Cha = 1; /* unhide the trap */ 1059 tmp2->stats.Cha = 1; /* unhide the trap */
963 } 1060 }
964 } 1061 }
965 } 1062 }
966 if((tmp->type==RUNE || tmp->type == TRAP) && trap_see(pl,tmp)) { 1063 if ((tmp->type == RUNE || tmp->type == TRAP) && trap_see (pl, tmp))
967 trap_show(tmp,tmp); 1064 {
968 if(tmp->stats.Cha>1) { 1065 trap_show (tmp, tmp);
1066 if (tmp->stats.Cha > 1)
1067 {
969 if (!tmp->owner || tmp->owner->type!=PLAYER) 1068 if (!tmp->owner || tmp->owner->type != PLAYER)
970 expsum += calc_skill_exp(pl,tmp, skill); 1069 expsum += calc_skill_exp (pl, tmp, skill);
971 tmp->stats.Cha = 1; /* unhide the trap */ 1070 tmp->stats.Cha = 1; /* unhide the trap */
972 } 1071 }
1072 }
1073 }
973 } 1074 }
974 }
975 }
976 new_draw_info(NDI_BLACK, 0, pl, "You search the area."); 1075 new_draw_info (NDI_BLACK, 0, pl, "You search the area.");
977 return expsum; 1076 return expsum;
978} 1077}
979 1078
980/* remove_trap() - This skill will disarm any previously discovered trap 1079/* remove_trap() - This skill will disarm any previously discovered trap
981 * 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.
982 */ 1081 */
983 1082
1083int
984int remove_trap (object *op, int dir, object *skill) { 1084remove_trap (object *op, int dir, object *skill)
1085{
985 object *tmp,*tmp2; 1086 object *tmp, *tmp2;
986 int i,success=0,mflags; 1087 int i, success = 0, mflags;
987 mapstruct *m; 1088 maptile *m;
988 sint16 x,y; 1089 sint16 x, y;
989 1090
990 for(i=0;i<9;i++) { 1091 for (i = 0; i < 9; i++)
1092 {
991 x = op->x + freearr_x[i]; 1093 x = op->x + freearr_x[i];
992 y = op->y + freearr_y[i]; 1094 y = op->y + freearr_y[i];
993 m = op->map; 1095 m = op->map;
994 1096
995 mflags =get_map_flags(m, &m, x,y, &x, &y); 1097 mflags = get_map_flags (m, &m, x, y, &x, &y);
996 if (mflags & P_OUT_OF_MAP) continue; 1098 if (mflags & P_OUT_OF_MAP)
1099 continue;
997 1100
998 /* Check everything in the square for trapness */ 1101 /* Check everything in the square for trapness */
999 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 {
1000 /* And now we'd better do an inventory traversal of each 1104 /* And now we'd better do an inventory traversal of each
1001 * of these objects inventory. Like above, only 1105 * of these objects inventory. Like above, only
1002 * do this for interesting objects. 1106 * do this for interesting objects.
1003 */ 1107 */
1004 1108
1005 if (tmp->type != PLAYER && !QUERY_FLAG(tmp, FLAG_MONSTER)) { 1109 if (tmp->type != PLAYER && !QUERY_FLAG (tmp, FLAG_MONSTER))
1110 {
1006 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 }
1007 if((tmp2->type==RUNE || tmp2->type == TRAP) && tmp2->stats.Cha<=1) { 1122 if ((tmp->type == RUNE || tmp->type == TRAP) && tmp->stats.Cha <= 1)
1008 trap_show(tmp2,tmp); 1123 {
1124 trap_show (tmp, tmp);
1009 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 {
1010 tmp->stats.exp = tmp->stats.Cha * tmp->level; 1127 tmp->stats.exp = tmp->stats.Cha * tmp->level;
1011 success += calc_skill_exp(op,tmp2, skill); 1128 success += calc_skill_exp (op, tmp, skill);
1012 } 1129 }
1013 } 1130 }
1131 }
1014 } 1132 }
1015 if((tmp->type==RUNE || tmp->type==TRAP) && tmp->stats.Cha<=1) {
1016 trap_show(tmp,tmp);
1017 if (trap_disarm(op,tmp,1,skill) && (!tmp->owner || tmp->owner->type!=PLAYER)) {
1018 tmp->stats.exp = tmp->stats.Cha * tmp->level;
1019 success += calc_skill_exp(op,tmp,skill);
1020 }
1021 }
1022 }
1023 }
1024 return success; 1133 return success;
1025} 1134}
1026 1135
1027 1136
1028/* pray() - when this skill is called from do_skill(), it allows 1137/* pray() - when this skill is called from do_skill(), it allows
1029 * 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.
1031 * 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
1032 * 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
1033 * give infinite exp by returning true in any cases. 1142 * give infinite exp by returning true in any cases.
1034 */ 1143 */
1035 1144
1145int
1036int pray (object *pl, object *skill) { 1146pray (object *pl, object *skill)
1147{
1037 char buf[MAX_BUF]; 1148 char buf[MAX_BUF];
1038 object *tmp; 1149 object *tmp;
1039 1150
1040 if(pl->type!=PLAYER) return 0; 1151 if (pl->type != PLAYER)
1041
1042 strcpy(buf,"You pray.");
1043
1044 /* Check all objects - we could stop at floor objects,
1045 * but if someone buries an altar, I don't see a problem with
1046 * going through all the objects, and it shouldn't be much slower
1047 * than extra checks on object attributes.
1048 */
1049 for (tmp=pl->below; tmp!=NULL; tmp=tmp->below) {
1050 /* Only if the altar actually belongs to someone do you get special benefits */
1051 if(tmp && tmp->type==HOLY_ALTAR && tmp->other_arch) {
1052 sprintf(buf,"You pray over the %s.",tmp->name);
1053 pray_at_altar(pl,tmp, skill);
1054 break; /* Only pray at one altar */
1055 }
1056 }
1057
1058 new_draw_info(NDI_BLACK,0,pl,buf);
1059
1060 if(pl->stats.grace < pl->stats.maxgrace) {
1061 pl->stats.grace++;
1062 pl->last_grace = -1;
1063 }
1064 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;
1065} 1180}
1066 1181
1067/* 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
1068 * brief period of concentration. No armour or weapons may be 1183 * brief period of concentration. No armour or weapons may be
1069 * wielded/applied for this to work. The amount of time needed 1184 * wielded/applied for this to work. The amount of time needed
1070 * to concentrate and the # of points regained is dependant on 1185 * to concentrate and the # of points regained is dependant on
1071 * the level of the user. - b.t. thomas@astro.psu.edu 1186 * the level of the user. - b.t. thomas@astro.psu.edu
1072 */ 1187 */
1073 1188
1189void
1074void meditate (object *pl, object *skill) { 1190meditate (object *pl, object *skill)
1191{
1075 object *tmp; 1192 object *tmp;
1076 1193
1077 if(pl->type!=PLAYER) return; /* players only */ 1194 if (pl->type != PLAYER)
1195 return; /* players only */
1078 1196
1079 /* check if pl has removed encumbering armour and weapons */ 1197 /* check if pl has removed encumbering armour and weapons */
1080 if(QUERY_FLAG(pl,FLAG_READY_WEAPON) && (skill->level<6)) { 1198 if (QUERY_FLAG (pl, FLAG_READY_WEAPON) && (skill->level < 6))
1081 new_draw_info(NDI_UNIQUE,0,pl, 1199 {
1082 "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");
1083 return; 1201 return;
1084 } else { 1202 }
1203 else
1204 {
1085 for(tmp=pl->inv;tmp;tmp=tmp->below) 1205 for (tmp = pl->inv; tmp; tmp = tmp->below)
1086 if (( (tmp->type==ARMOUR && skill->level<12) 1206 if (((tmp->type == ARMOUR && skill->level < 12)
1087 || (tmp->type==HELMET && skill->level<10) 1207 || (tmp->type == HELMET && skill->level < 10)
1088 || (tmp->type==SHIELD && skill->level<6) 1208 || (tmp->type == SHIELD && skill->level < 6)
1089 || (tmp->type==BOOTS && skill->level<4) 1209 || (tmp->type == BOOTS && skill->level < 4) || (tmp->type == GLOVES && skill->level < 2)) && QUERY_FLAG (tmp, FLAG_APPLIED))
1090 || (tmp->type==GLOVES && skill->level<2) ) 1210 {
1091 && QUERY_FLAG(tmp,FLAG_APPLIED)) { 1211 new_draw_info (NDI_UNIQUE, 0, pl, "You can't concentrate while wearing so much armour!\n");
1092 new_draw_info(NDI_UNIQUE,0,pl, 1212 return;
1093 "You can't concentrate while wearing so much armour!\n"); 1213 }
1094 return;
1095 }
1096 } 1214 }
1097 1215
1098 /* ok let's meditate! Spell points are regained first, then once 1216 /* ok let's meditate! Spell points are regained first, then once
1099 * they are maxed we get back hp. Actual incrementing of values 1217 * they are maxed we get back hp. Actual incrementing of values
1100 * 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
1101 * bonuses for healing/sp regeneration are included properly 1219 * bonuses for healing/sp regeneration are included properly
1102 * 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
1103 * meditate. (see 'factor' variable for what sets the amount of time) 1221 * meditate. (see 'factor' variable for what sets the amount of time)
1104 */ 1222 */
1105 1223
1106 new_draw_info(NDI_BLACK,0,pl, "You meditate."); 1224 new_draw_info (NDI_BLACK, 0, pl, "You meditate.");
1107 1225
1108 if(pl->stats.sp < pl->stats.maxsp) { 1226 if (pl->stats.sp < pl->stats.maxsp)
1227 {
1109 pl->stats.sp++; 1228 pl->stats.sp++;
1110 pl->last_sp = -1; 1229 pl->last_sp = -1;
1230 }
1111 } else if (pl->stats.hp < pl->stats.maxhp) { 1231 else if (pl->stats.hp < pl->stats.maxhp)
1232 {
1112 pl->stats.hp++; 1233 pl->stats.hp++;
1113 pl->last_heal = -1; 1234 pl->last_heal = -1;
1114 } 1235 }
1115} 1236}
1116 1237
1117/* write_note() - this routine allows players to inscribe messages in 1238/* write_note() - this routine allows players to inscribe messages in
1118 * ordinary 'books' (anything that is type BOOK). b.t. 1239 * ordinary 'books' (anything that is type BOOK). b.t.
1119 */ 1240 */
1120 1241
1242static int
1121static int write_note(object *pl, object *item, const char *msg, object *skill) { 1243write_note (object *pl, object *item, const char *msg, object *skill)
1244{
1122 char buf[1024]; 1245 char buf[1024];
1123 object *newBook = NULL; 1246 object *newBook = NULL;
1124 1247
1125 /* a pair of sanity checks */ 1248 /* a pair of sanity checks */
1126 if(!item||item->type!=BOOK) return 0; 1249 if (!item || item->type != BOOK)
1127
1128 if(!msg) {
1129 new_draw_info(NDI_UNIQUE,0,pl,"No message to write!");
1130 new_draw_info_format(NDI_UNIQUE,0,pl,"Usage: use_skill %s <message>",
1131 skill->skill);
1132 return 0;
1133 }
1134 if (strcasestr_local(msg, "endmsg")) {
1135 new_draw_info(NDI_UNIQUE,0,pl,"Trying to cheat now are we?");
1136 return 0;
1137 }
1138
1139 /* Lauwenmark: Handle for plugin book writing (trigger) event */
1140 if (execute_event(item, EVENT_TRIGGER,pl,NULL,msg,SCRIPT_FIX_ALL)!=0)
1141 return strlen(msg);
1142
1143 buf[0] = 0;
1144 if(!book_overflow(item->msg,msg,sizeof (buf))) { /* add msg string to book */
1145 if(item->msg)
1146 strcpy(buf,item->msg);
1147
1148 strcat(buf,msg);
1149 strcat(buf,"\n"); /* new msg needs a LF */
1150 if(item->nrof > 1) {
1151 newBook = get_object();
1152 copy_object(item, newBook);
1153 decrease_ob(item);
1154 esrv_send_item(pl, item);
1155 newBook->nrof = 1;
1156 if (newBook->msg) free_string(newBook->msg);
1157 newBook->msg = add_string(buf);
1158 newBook = insert_ob_in_ob(newBook, pl);
1159 esrv_send_item(pl, newBook);
1160 } else {
1161 if (item->msg) free_string(item->msg);
1162 item->msg=add_string(buf);
1163 /* This shouldn't be necessary - the object hasn't changed in any
1164 * visible way
1165 */
1166 /* esrv_send_item(pl, item);*/
1167 }
1168 new_draw_info_format(NDI_UNIQUE,0,pl, "You write in the %s.",
1169 query_short_name(item));
1170 return strlen(msg);
1171 } else
1172 new_draw_info_format(NDI_UNIQUE,0,pl,
1173 "Your message won't fit in the %s!",
1174 query_short_name(item));
1175
1176 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;
1177} 1301}
1178 1302
1179/* write_scroll() - this routine allows players to inscribe spell scrolls 1303/* write_scroll() - this routine allows players to inscribe spell scrolls
1180 * of spells which they know. Backfire effects are possible with the 1304 * of spells which they know. Backfire effects are possible with the
1181 * severity of the backlash correlated with the difficulty of the scroll 1305 * severity of the backlash correlated with the difficulty of the scroll
1182 * that is attempted. -b.t. thomas@astro.psu.edu 1306 * that is attempted. -b.t. thomas@astro.psu.edu
1183 */ 1307 */
1184 1308
1309static int
1185static int write_scroll (object *pl, object *scroll, object *skill) { 1310write_scroll (object *pl, object *scroll, object *skill)
1311{
1186 int success=0,confused=0; 1312 int success = 0, confused = 0;
1187 object *newscroll, *chosen_spell, *tmp; 1313 object *newscroll, *chosen_spell, *tmp;
1188 1314
1189 /* this is a sanity check */ 1315 /* this is a sanity check */
1190 if (scroll->type!=SCROLL) { 1316 if (scroll->type != SCROLL)
1317 {
1191 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!");
1192 return 0; 1319 return 0;
1193 } 1320 }
1194 1321
1195 /* Check if we are ready to attempt inscription */ 1322 /* Check if we are ready to attempt inscription */
1196 chosen_spell=pl->contr->ranges[range_magic]; 1323 chosen_spell = pl->contr->ranges[range_magic];
1197 if(!chosen_spell) { 1324 if (!chosen_spell)
1198 new_draw_info(NDI_UNIQUE,0,pl,
1199 "You need a spell readied in order to inscribe!");
1200 return 0;
1201 } 1325 {
1326 new_draw_info (NDI_UNIQUE, 0, pl, "You need a spell readied in order to inscribe!");
1327 return 0;
1328 }
1202 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)
1203 new_draw_info_format(NDI_UNIQUE,0,pl,
1204 "You don't have enough grace to write a scroll of %s.",
1205 chosen_spell->name);
1206 return 0;
1207 } 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 }
1208 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)
1209 new_draw_info_format(NDI_UNIQUE,0,pl,
1210 "You don't have enough mana to write a scroll of %s.",
1211 chosen_spell->name);
1212 return 0;
1213 } 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 }
1214 1339
1215 /* 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
1216 * 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
1217 * a 50% chance to overwrite spell at their own level 1342 * a 50% chance to overwrite spell at their own level
1218 */ 1343 */
1219 if((scroll->stats.sp || scroll->inv) && 1344 if ((scroll->stats.sp || scroll->inv) && random_roll (0, scroll->level * 2, pl, PREFER_LOW) > skill->level)
1220 random_roll(0, scroll->level*2, pl, PREFER_LOW)>skill->level) { 1345 {
1221 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.");
1222 "Oops! You accidently read it while trying to write on it.");
1223 manual_apply(pl,scroll,0); 1347 manual_apply (pl, scroll, 0);
1224 return 0; 1348 return 0;
1225 } 1349 }
1226 1350
1227 /* ok, we are ready to try inscription */ 1351 /* ok, we are ready to try inscription */
1228 if(QUERY_FLAG(pl,FLAG_CONFUSED)) confused = 1; 1352 if (QUERY_FLAG (pl, FLAG_CONFUSED))
1353 confused = 1;
1229 1354
1230 /* Lost mana/grace no matter what */ 1355 /* Lost mana/grace no matter what */
1231 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);
1232 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);
1233 1358
1234 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 {
1235 if (scroll->nrof > 1) { 1361 if (scroll->nrof > 1)
1362 {
1236 newscroll = get_object(); 1363 newscroll = get_object ();
1237 copy_object(scroll, newscroll); 1364 copy_object (scroll, newscroll);
1238 decrease_ob(scroll); 1365 decrease_ob (scroll);
1239 newscroll->nrof = 1; 1366 newscroll->nrof = 1;
1240 } else { 1367 }
1368 else
1369 {
1241 newscroll = scroll; 1370 newscroll = scroll;
1242 } 1371 }
1243 1372
1244 if(!confused) { 1373 if (!confused)
1374 {
1245 newscroll->level= MAX(skill->level, chosen_spell->level); 1375 newscroll->level = MAX (skill->level, chosen_spell->level);
1246 new_draw_info(NDI_UNIQUE,0,pl, 1376 new_draw_info (NDI_UNIQUE, 0, pl, "You succeed in writing a new scroll.");
1247 "You succeed in writing a new scroll."); 1377 }
1248 } else { 1378 else
1379 {
1249 chosen_spell = find_random_spell_in_ob(pl, NULL); 1380 chosen_spell = find_random_spell_in_ob (pl, NULL);
1250 if (!chosen_spell) return 0; 1381 if (!chosen_spell)
1382 return 0;
1251 1383
1252 newscroll->level= MAX(skill->level, chosen_spell->level); 1384 newscroll->level = MAX (skill->level, chosen_spell->level);
1253 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.");
1254 "In your confused state, you write down some odd spell."); 1386 }
1255 }
1256 1387
1257 if (newscroll->inv) { 1388 if (newscroll->inv)
1389 {
1258 object *ninv; 1390 object *ninv;
1259 1391
1260 ninv = newscroll->inv; 1392 ninv = newscroll->inv;
1261 remove_ob(ninv); 1393 remove_ob (ninv);
1262 free_object(ninv); 1394 free_object (ninv);
1263 } 1395 }
1264 tmp = get_object(); 1396 tmp = get_object ();
1265 copy_object(chosen_spell, tmp); 1397 copy_object (chosen_spell, tmp);
1266 insert_ob_in_ob(tmp, newscroll); 1398 insert_ob_in_ob (tmp, newscroll);
1267 1399
1268 /* Same code as from treasure.c - so they can better merge. 1400 /* Same code as from treasure.c - so they can better merge.
1269 * if players want to sell them, so be it. 1401 * if players want to sell them, so be it.
1270 */ 1402 */
1271 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);
1272 (newscroll->level +50) / (newscroll->inv->level + 50);
1273 newscroll->stats.exp = newscroll->value/5; 1404 newscroll->stats.exp = newscroll->value / 5;
1274 1405
1275 /* wait until finished manipulating the scroll before inserting it */ 1406 /* wait until finished manipulating the scroll before inserting it */
1276 if (newscroll == scroll) 1407 if (newscroll == scroll)
1277 { 1408 {
1278 /* 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 */
1279 remove_ob(newscroll); 1410 remove_ob (newscroll);
1280 esrv_del_item(pl->contr,newscroll->count); 1411 esrv_del_item (pl->contr, newscroll->count);
1281 } 1412 }
1282 newscroll=insert_ob_in_ob(newscroll,pl); 1413 newscroll = insert_ob_in_ob (newscroll, pl);
1283 esrv_send_item(pl, newscroll); 1414 esrv_send_item (pl, newscroll);
1284 success = calc_skill_exp(pl,newscroll, skill); 1415 success = calc_skill_exp (pl, newscroll, skill);
1285 if(!confused) success *= 2; 1416 if (!confused)
1417 success *= 2;
1286 success = success * skill->level; 1418 success = success * skill->level;
1287 return success; 1419 return success;
1288 1420
1289 } else { /* Inscription has failed */ 1421 }
1422 else
1423 { /* Inscription has failed */
1290 1424
1291 if(chosen_spell->level>skill->level || confused) { /*backfire!*/ 1425 if (chosen_spell->level > skill->level || confused)
1292 new_draw_info(NDI_UNIQUE,0,pl, 1426 { /*backfire! */
1293 "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!");
1294 if(random_roll(0, 1, pl, PREFER_LOW)==1) 1428 if (random_roll (0, 1, pl, PREFER_LOW) == 1)
1295 drain_specific_stat(pl,4); 1429 drain_specific_stat (pl, 4);
1296 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!");
1297 confuse_player(pl,pl,99); 1439 confuse_player (pl, pl, 99);
1298 return (-30*chosen_spell->level); 1440 }
1299 } 1441 else
1300 } else if(random_roll(0, pl->stats.Int-1, pl, PREFER_HIGH) < 15) {
1301 new_draw_info(NDI_UNIQUE,0,pl,
1302 "Your attempt to write a new scroll rattles your mind!");
1303 confuse_player(pl,pl,99);
1304 } else
1305 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.");
1306 } 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)
1307 return 0; 1457 return 0;
1308}
1309 1458
1310/* write_on_item() - wrapper for write_note and write_scroll */
1311int write_on_item (object *pl,const char *params, object *skill) {
1312 object *item;
1313 const char *string=params;
1314 int msgtype;
1315 archetype *skat;
1316
1317 if(pl->type!=PLAYER) return 0;
1318
1319 if (!params) { 1459 if (!params)
1320 params="";
1321 string=params;
1322 } 1460 {
1461 params = "";
1462 string = params;
1463 }
1323 skat = get_archetype_by_type_subtype(SKILL, SK_LITERACY); 1464 skat = get_archetype_by_type_subtype (SKILL, SK_LITERACY);
1324 1465
1325 /* Need to be able to read before we can write! */ 1466 /* Need to be able to read before we can write! */
1326 if(!find_skill_by_name(pl,skat->clone.skill)) { 1467 if (!find_skill_by_name (pl, skat->clone.skill))
1327 new_draw_info(NDI_UNIQUE,0,pl,
1328 "You must learn to read before you can write!");
1329 return 0;
1330 } 1468 {
1469 new_draw_info (NDI_UNIQUE, 0, pl, "You must learn to read before you can write!");
1470 return 0;
1471 }
1331 1472
1332 /* 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
1333 * write active spell into the scroll 1474 * write active spell into the scroll
1334 */ 1475 */
1335 msgtype = (string[0]!='\0') ? BOOK : SCROLL; 1476 msgtype = (string[0] != '\0') ? BOOK : SCROLL;
1336 1477
1337 /* find an item of correct type to write on */ 1478 /* find an item of correct type to write on */
1338 if ( !(item = find_marked_object(pl))){ 1479 if (!(item = find_marked_object (pl)))
1480 {
1339 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.");
1340 return 0; 1482 return 0;
1341 } 1483 }
1342 1484
1343 if(QUERY_FLAG(item,FLAG_UNPAID)) { 1485 if (QUERY_FLAG (item, FLAG_UNPAID))
1344 new_draw_info(NDI_UNIQUE,0,pl,
1345 "You had better pay for that before you write on it.");
1346 return 0;
1347 } 1486 {
1487 new_draw_info (NDI_UNIQUE, 0, pl, "You had better pay for that before you write on it.");
1488 return 0;
1489 }
1348 if (msgtype != item->type) { 1490 if (msgtype != item->type)
1349 new_draw_info_format(NDI_UNIQUE,0,pl,"You have no %s to write on",
1350 msgtype==BOOK ? "book" : "scroll");
1351 return 0;
1352 } 1491 {
1353 1492 new_draw_info_format (NDI_UNIQUE, 0, pl, "You have no %s to write on", msgtype == BOOK ? "book" : "scroll");
1354 if (msgtype == SCROLL) {
1355 return write_scroll(pl,item, skill);
1356 } else if (msgtype == BOOK) {
1357 return write_note(pl,item,string, skill);
1358 }
1359 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;
1360} 1505}
1361 1506
1362 1507
1363 1508
1364/* find_throw_ob() - if we request an object, then 1509/* find_throw_ob() - if we request an object, then
1368 * (that is "throwable", ie no throwing your skills away!) 1513 * (that is "throwable", ie no throwing your skills away!)
1369 * 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
1370 * 'throwable' (ie not applied cursed obj, worn, etc). 1515 * 'throwable' (ie not applied cursed obj, worn, etc).
1371 */ 1516 */
1372 1517
1518static object *
1373static object *find_throw_ob( object *op, const char *request ) { 1519find_throw_ob (object *op, const char *request)
1520{
1374 object *tmp; 1521 object *tmp;
1375 1522
1376 if(!op) { /* safety */ 1523 if (!op)
1524 { /* safety */
1377 LOG(llevError,"find_throw_ob(): confused! have a NULL thrower!\n"); 1525 LOG (llevError, "find_throw_ob(): confused! have a NULL thrower!\n");
1378 return (object *) NULL; 1526 return (object *) NULL;
1379 } 1527 }
1380 1528
1381 /* prefer marked item */ 1529 /* prefer marked item */
1382 tmp = find_marked_object(op); 1530 tmp = find_marked_object (op);
1383 if (tmp != NULL) { 1531 if (tmp != NULL)
1532 {
1384 /* can't toss invisible or inv-locked items */ 1533 /* can't toss invisible or inv-locked items */
1385 if (tmp->invisible || QUERY_FLAG(tmp, FLAG_INV_LOCKED)) { 1534 if (tmp->invisible || QUERY_FLAG (tmp, FLAG_INV_LOCKED))
1535 {
1386 tmp = NULL; 1536 tmp = NULL;
1387 } 1537 }
1388 } 1538 }
1389 1539
1390 /* look through the inventory */ 1540 /* look through the inventory */
1391 if (tmp == NULL) { 1541 if (tmp == NULL)
1542 {
1392 for (tmp = op->inv; tmp != NULL; tmp = tmp->below) { 1543 for (tmp = op->inv; tmp != NULL; tmp = tmp->below)
1544 {
1393 /* can't toss invisible or inv-locked items */ 1545 /* can't toss invisible or inv-locked items */
1394 if (tmp->invisible || QUERY_FLAG(tmp, FLAG_INV_LOCKED)) 1546 if (tmp->invisible || QUERY_FLAG (tmp, FLAG_INV_LOCKED))
1395 continue; 1547 continue;
1396 if (!request 1548 if (!request || !strcmp (query_name (tmp), request) || !strcmp (tmp->name, request))
1397 || !strcmp(query_name(tmp), request)
1398 || !strcmp(tmp->name, request))
1399 break; 1549 break;
1400 } 1550 }
1401 } 1551 }
1402 1552
1403 /* this should prevent us from throwing away 1553 /* this should prevent us from throwing away
1404 * cursed items, worn armour, etc. Only weapons 1554 * cursed items, worn armour, etc. Only weapons
1405 * can be thrown from 'hand'. 1555 * can be thrown from 'hand'.
1406 */ 1556 */
1557 if (!tmp)
1407 if (!tmp) return NULL; 1558 return NULL;
1408 1559
1409 if (QUERY_FLAG(tmp,FLAG_APPLIED)) { 1560 if (QUERY_FLAG (tmp, FLAG_APPLIED))
1561 {
1410 if(tmp->type!=WEAPON) { 1562 if (tmp->type != WEAPON)
1411 new_draw_info_format(NDI_UNIQUE, 0,op, 1563 {
1412 "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));
1413 tmp = NULL; 1565 tmp = NULL;
1566 }
1414 } 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))
1415 new_draw_info_format(NDI_UNIQUE, 0,op, 1568 {
1416 "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));
1417 tmp = NULL; 1570 tmp = NULL;
1418 } else { 1571 }
1572 else
1573 {
1419 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE)) { 1574 if (apply_special (op, tmp, AP_UNAPPLY | AP_NO_MERGE))
1575 {
1420 LOG (llevError, "BUG: find_throw_ob(): couldn't unapply\n"); 1576 LOG (llevError, "BUG: find_throw_ob(): couldn't unapply\n");
1421 tmp = NULL; 1577 tmp = NULL;
1578 }
1579 }
1422 } 1580 }
1423 }
1424 } else if (QUERY_FLAG(tmp, FLAG_UNPAID)) { 1581 else if (QUERY_FLAG (tmp, FLAG_UNPAID))
1582 {
1425 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));
1426 tmp = NULL; 1584 tmp = NULL;
1427 } 1585 }
1428 1586
1429 if (tmp && QUERY_FLAG (tmp, FLAG_INV_LOCKED)) { 1587 if (tmp && QUERY_FLAG (tmp, FLAG_INV_LOCKED))
1588 {
1430 LOG (llevError, "BUG: find_throw_ob(): object is locked\n"); 1589 LOG (llevError, "BUG: find_throw_ob(): object is locked\n");
1431 tmp=NULL; 1590 tmp = NULL;
1432 } 1591 }
1433 return tmp; 1592 return tmp;
1434} 1593}
1435 1594
1436/* make_throw_ob() We construct the 'carrier' object in 1595/* make_throw_ob() We construct the 'carrier' object in
1437 * which we will insert the object that is being thrown. 1596 * which we will insert the object that is being thrown.
1438 * This combination becomes the 'thrown object'. -b.t. 1597 * This combination becomes the 'thrown object'. -b.t.
1439 */ 1598 */
1440 1599
1600static object *
1441static object *make_throw_ob (object *orig) { 1601make_throw_ob (object *orig)
1602{
1442 object *toss_item; 1603 object *toss_item;
1443 1604
1605 if (!orig)
1444 if(!orig) return NULL; 1606 return NULL;
1445 1607
1446 toss_item=get_object(); 1608 toss_item = get_object ();
1447 if (QUERY_FLAG (orig, FLAG_APPLIED)) { 1609 if (QUERY_FLAG (orig, FLAG_APPLIED))
1610 {
1448 LOG (llevError, "BUG: make_throw_ob(): ob is applied\n"); 1611 LOG (llevError, "BUG: make_throw_ob(): ob is applied\n");
1449 /* insufficient workaround, but better than nothing */ 1612 /* insufficient workaround, but better than nothing */
1450 CLEAR_FLAG (orig, FLAG_APPLIED); 1613 CLEAR_FLAG (orig, FLAG_APPLIED);
1451 } 1614 }
1452 copy_object(orig,toss_item); 1615 copy_object (orig, toss_item);
1453 toss_item->type = THROWN_OBJ; 1616 toss_item->type = THROWN_OBJ;
1454 CLEAR_FLAG(toss_item,FLAG_CHANGING); 1617 CLEAR_FLAG (toss_item, FLAG_CHANGING);
1455 toss_item->stats.dam = 0; /* default damage */ 1618 toss_item->stats.dam = 0; /* default damage */
1456 insert_ob_in_ob(orig,toss_item); 1619 insert_ob_in_ob (orig, toss_item);
1457 return toss_item; 1620 return toss_item;
1458} 1621}
1459 1622
1460 1623
1461/* do_throw() - op throws any object toss_item. This code 1624/* do_throw() - op throws any object toss_item. This code
1462 * was borrowed from fire_bow. 1625 * was borrowed from fire_bow.
1463 * Returns 1 if skill was successfully used, 0 if not 1626 * Returns 1 if skill was successfully used, 0 if not
1464 */ 1627 */
1465 1628
1629static int
1466static 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{
1467 object *throw_ob=toss_item, *left=NULL; 1632 object *throw_ob = toss_item, *left = NULL;
1468 tag_t left_tag;
1469 int eff_str = 0,maxc,str=op->stats.Str,dam=0; 1633 int eff_str = 0, maxc, str = op->stats.Str, dam = 0;
1470 int pause_f,weight_f=0, mflags; 1634 int pause_f, weight_f = 0, mflags;
1471 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;
1472 mapstruct *m; 1636 maptile *m;
1473 sint16 sx, sy; 1637 sint16 sx, sy;
1474 tag_t tag;
1475 1638
1476 if(throw_ob==NULL) { 1639 if (throw_ob == NULL)
1640 {
1477 if(op->type==PLAYER) { 1641 if (op->type == PLAYER)
1478 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.");
1479 } 1643
1480 return 0; 1644 return 0;
1481 } 1645 }
1482 if (QUERY_FLAG(throw_ob, FLAG_STARTEQUIP)) { 1646 if (QUERY_FLAG (throw_ob, FLAG_STARTEQUIP))
1647 {
1483 if (op->type==PLAYER) { 1648 if (op->type == PLAYER)
1484 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.");
1485 }
1486 return 0;
1487 }
1488 1650
1651 return 0;
1652 }
1653
1489 /* Because throwing effectiveness must be reduced by the 1654 /* Because throwing effectiveness must be reduced by the
1490 * encumbrance of the thrower and weight of the object. THus, 1655 * encumbrance of the thrower and weight of the object. THus,
1491 * we use the concept of 'effective strength' as defined below. 1656 * we use the concept of 'effective strength' as defined below.
1492 */ 1657 */
1493 1658
1494 /* 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 */
1495 if(str>MAX_STAT) { 1660 if (str > MAX_STAT)
1496 str_factor = (float) str /(float) MAX_STAT; str = MAX_STAT;
1497 } 1661 {
1662 str_factor = (float) str / (float) MAX_STAT;
1663 str = MAX_STAT;
1498 1664 }
1665
1499 /* 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 */
1500 maxc=max_carry[str]*1000; 1667 maxc = max_carry[str] * 1000;
1501 if(op->carrying>maxc&&op->type==PLAYER) 1668 if (op->carrying > maxc && op->type == PLAYER)
1502 load_factor = (float)maxc/(float) op->carrying; 1669 load_factor = (float) maxc / (float) op->carrying;
1503 1670
1504 /* lighter items are thrown harder, farther, faster */ 1671 /* lighter items are thrown harder, farther, faster */
1505 if(throw_ob->weight>0) 1672 if (throw_ob->weight > 0)
1506 item_factor = (float) maxc/(float) (3.0 * throw_ob->weight); 1673 item_factor = (float) maxc / (float) (3.0 * throw_ob->weight);
1674 else
1507 else { /* 0 or negative weight?!? Odd object, can't throw it */ 1675 { /* 0 or negative weight?!? Odd object, can't throw it */
1508 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));
1509 query_name(throw_ob)); 1677 return 0;
1510 return 0;
1511 }
1512 1678 }
1679
1513 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));
1514 eff_str = (int) ((float) eff_str * item_factor * str_factor); 1681 eff_str = (int) ((float) eff_str * item_factor * str_factor);
1515 1682
1516 /* 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
1517 * account for super-strong throwers. */ 1684 * account for super-strong throwers. */
1518 if(eff_str>MAX_STAT) eff_str=MAX_STAT; 1685 if (eff_str > MAX_STAT)
1686 eff_str = MAX_STAT;
1519 1687
1520#ifdef DEBUG_THROW 1688#ifdef DEBUG_THROW
1521 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);
1522 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);
1523 item_factor,load_factor,op->stats.Str);
1524 LOG(llevDebug," str_factor=%f\n",str_factor); 1691 LOG (llevDebug, " str_factor=%f\n", str_factor);
1525 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);
1526#endif 1693#endif
1527 1694
1528 /* 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
1529 * have no effective throwing strength, or you threw at something 1696 * have no effective throwing strength, or you threw at something
1530 * that flying objects can't get through. 1697 * that flying objects can't get through.
1531 */ 1698 */
1532 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);
1533 1700
1534 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))
1535 (GET_MAP_MOVE_BLOCK(m, sx, sy) & MOVE_FLY_LOW)) { 1702 {
1536 1703
1537 /* bounces off 'wall', and drops to feet */ 1704 /* bounces off 'wall', and drops to feet */
1538 remove_ob(throw_ob); 1705 remove_ob (throw_ob);
1539 throw_ob->x = part->x; throw_ob->y = part->y; 1706 throw_ob->x = part->x;
1707 throw_ob->y = part->y;
1540 insert_ob_in_map(throw_ob,part->map,op,0); 1708 insert_ob_in_map (throw_ob, part->map, op, 0);
1541 if(op->type==PLAYER) { 1709 if (op->type == PLAYER)
1710 {
1542 if(eff_str<=1) { 1711 if (eff_str <= 1)
1543 new_draw_info_format(NDI_UNIQUE, 0,op, 1712 {
1544 "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));
1545 query_name(throw_ob)); 1714 }
1546 }
1547 else if(!dir) { 1715 else if (!dir)
1716 {
1548 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));
1549 query_name(throw_ob)); 1718 }
1550 } 1719 else
1551 else
1552 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.");
1553 } 1721 }
1554 return 0; 1722 return 0;
1555 } /* if object can't be thrown */ 1723 } /* if object can't be thrown */
1556 1724
1557 left = throw_ob; /* these are throwing objects left to the player */ 1725 left = throw_ob; /* these are throwing objects left to the player */
1558 left_tag = left->count;
1559 1726
1560 /* 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?)
1561 * and returns NULL. We must use 'left' then 1728 * and returns NULL. We must use 'left' then
1562 */ 1729 */
1563 1730
1564 if((throw_ob = get_split_ob(throw_ob, 1))==NULL) { 1731 if ((throw_ob = get_split_ob (throw_ob, 1)) == NULL)
1732 {
1565 throw_ob = left; 1733 throw_ob = left;
1566 remove_ob(left); 1734 remove_ob (left);
1567 if (op->type==PLAYER) 1735 if (op->type == PLAYER)
1568 esrv_del_item(op->contr, left->count); 1736 esrv_del_item (op->contr, left->count);
1569 } 1737 }
1570 else if (op->type==PLAYER) { 1738 else if (op->type == PLAYER)
1571 if (was_destroyed (left, left_tag)) 1739 {
1740 if (left->destroyed ())
1572 esrv_del_item(op->contr, left_tag); 1741 esrv_del_item (op->contr, left->count);
1573 else 1742 else
1574 esrv_update_item(UPD_NROF, op, left); 1743 esrv_update_item (UPD_NROF, op, left);
1575 } 1744 }
1576 1745
1577 /* special case: throwing powdery substances like dust, dirt */ 1746 /* special case: throwing powdery substances like dust, dirt */
1578 if(throw_ob->type == POTION && throw_ob->subtype == POT_DUST) { 1747 if (throw_ob->type == POTION && throw_ob->subtype == POT_DUST)
1748 {
1579 cast_dust(op,throw_ob,dir); 1749 cast_dust (op, throw_ob, dir);
1580 return 1; 1750 return 1;
1581 } 1751 }
1582 1752
1583 /* Make a thrown object -- insert real object in a 'carrier' object. 1753 /* Make a thrown object -- insert real object in a 'carrier' object.
1584 * If unsuccessfull at making the "thrown_obj", we just reinsert 1754 * If unsuccessfull at making the "thrown_obj", we just reinsert
1585 * the original object back into inventory and exit 1755 * the original object back into inventory and exit
1586 */ 1756 */
1587 if((toss_item = make_throw_ob(throw_ob))) { 1757 if ((toss_item = make_throw_ob (throw_ob)))
1758 {
1588 throw_ob = toss_item; 1759 throw_ob = toss_item;
1589 if (throw_ob->skill) free_string(throw_ob->skill);
1590 throw_ob->skill = add_string(skill->skill); 1760 throw_ob->skill = skill->skill;
1761 }
1762 else
1591 } 1763 {
1592 else {
1593 insert_ob_in_ob(throw_ob,op); 1764 insert_ob_in_ob (throw_ob, op);
1594 return 0; 1765 return 0;
1595 } 1766 }
1596 1767
1597 set_owner(throw_ob,op); 1768 set_owner (throw_ob, op);
1598 /* 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)
1599 * 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
1600 * owner value so exp goes to the right place. 1771 * owner value so exp goes to the right place.
1601 */ 1772 */
1602 set_owner(throw_ob->inv,op); 1773 set_owner (throw_ob->inv, op);
1603 throw_ob->direction=dir; 1774 throw_ob->direction = dir;
1604 throw_ob->x = part->x; 1775 throw_ob->x = part->x;
1605 throw_ob->y = part->y; 1776 throw_ob->y = part->y;
1606 1777
1607 /* the damage bonus from the force of the throw */ 1778 /* the damage bonus from the force of the throw */
1608 dam = (int) (str_factor * dam_bonus[eff_str]); 1779 dam = (int) (str_factor * dam_bonus[eff_str]);
1609 1780
1610 /* Now, lets adjust the properties of the thrown_ob. */ 1781 /* Now, lets adjust the properties of the thrown_ob. */
1611 1782
1612 /* how far to fly */ 1783 /* how far to fly */
1613 throw_ob->last_sp = (eff_str*3)/5; 1784 throw_ob->last_sp = (eff_str * 3) / 5;
1614 1785
1615 /* speed */ 1786 /* speed */
1616 throw_ob->speed = (speed_bonus[eff_str]+1.0)/1.5; 1787 throw_ob->speed = (speed_bonus[eff_str] + 1.0) / 1.5;
1617 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! */
1618 1789
1619 /* item damage. Eff_str and item weight influence damage done */ 1790 /* item damage. Eff_str and item weight influence damage done */
1620 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);
1621 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;
1622 + (throw_ob->weight/15000) - 2;
1623 1793
1624 /* chance of breaking. Proportional to force used and weight of item */ 1794 /* chance of breaking. Proportional to force used and weight of item */
1625 throw_ob->stats.food = (dam/2) + (throw_ob->weight/60000); 1795 throw_ob->stats.food = (dam / 2) + (throw_ob->weight / 60000);
1626 1796
1627 /* 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 */
1628 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;
1629 - thaco_bonus[eff_str] - skill->level;
1630
1631 1799
1800
1632 /* 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,
1633 * throwing knife, etc) will differ from ordinary items. Lets tailor 1802 * throwing knife, etc) will differ from ordinary items. Lets tailor
1634 * this stuff in here. 1803 * this stuff in here.
1635 */ 1804 */
1636 1805
1637 if(QUERY_FLAG(throw_ob->inv,FLAG_IS_THROWN)) { 1806 if (QUERY_FLAG (throw_ob->inv, FLAG_IS_THROWN))
1807 {
1638 throw_ob->last_sp += eff_str/3; /* fly a little further */ 1808 throw_ob->last_sp += eff_str / 3; /* fly a little further */
1639 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;
1640 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;
1641 /* only throw objects get directional faces */ 1811 /* only throw objects get directional faces */
1642 if(GET_ANIM_ID(throw_ob) && NUM_ANIMATIONS(throw_ob)) 1812 if (GET_ANIM_ID (throw_ob) && NUM_ANIMATIONS (throw_ob))
1643 SET_ANIMATION(throw_ob, dir); 1813 SET_ANIMATION (throw_ob, dir);
1644 } else { 1814 }
1815 else
1816 {
1645 /* some materials will adjust properties.. */ 1817 /* some materials will adjust properties.. */
1646 if(throw_ob->material&M_LEATHER) { 1818 if (throw_ob->material & M_LEATHER)
1819 {
1647 throw_ob->stats.dam -= 1; 1820 throw_ob->stats.dam -= 1;
1648 throw_ob->stats.food -= 10; 1821 throw_ob->stats.food -= 10;
1649 } 1822 }
1650 if(throw_ob->material&M_GLASS) throw_ob->stats.food += 60; 1823 if (throw_ob->material & M_GLASS)
1651 1824 throw_ob->stats.food += 60;
1825
1652 if(throw_ob->material&M_ORGANIC) { 1826 if (throw_ob->material & M_ORGANIC)
1827 {
1653 throw_ob->stats.dam -= 3; 1828 throw_ob->stats.dam -= 3;
1654 throw_ob->stats.food += 55; 1829 throw_ob->stats.food += 55;
1655 } 1830 }
1656 if(throw_ob->material&M_PAPER||throw_ob->material&M_CLOTH) { 1831 if (throw_ob->material & M_PAPER || throw_ob->material & M_CLOTH)
1657 throw_ob->stats.dam -= 5; throw_ob->speed *= 0.8; 1832 {
1658 throw_ob->stats.wc += 3; throw_ob->stats.food -= 30; 1833 throw_ob->stats.dam -= 5;
1659 } 1834 throw_ob->speed *= 0.8;
1835 throw_ob->stats.wc += 3;
1836 throw_ob->stats.food -= 30;
1837 }
1660 /* light obj have more wind resistance, fly slower*/ 1838 /* light obj have more wind resistance, fly slower */
1661 if(throw_ob->weight>500) throw_ob->speed *= 0.8; 1839 if (throw_ob->weight > 500)
1662 if(throw_ob->weight>50) throw_ob->speed *= 0.5; 1840 throw_ob->speed *= 0.8;
1663 1841 if (throw_ob->weight > 50)
1664 } /* else tailor thrown object */ 1842 throw_ob->speed *= 0.5;
1665 1843
1844 } /* else tailor thrown object */
1845
1666 /* some limits, and safeties (needed?) */ 1846 /* some limits, and safeties (needed?) */
1667 if(throw_ob->stats.dam<0) throw_ob->stats.dam=0; 1847 if (throw_ob->stats.dam < 0)
1668 if(throw_ob->last_sp>eff_str) throw_ob->last_sp=eff_str; 1848 throw_ob->stats.dam = 0;
1669 if(throw_ob->stats.food<0) throw_ob->stats.food=0; 1849 if (throw_ob->last_sp > eff_str)
1670 if(throw_ob->stats.food>100) throw_ob->stats.food=100; 1850 throw_ob->last_sp = eff_str;
1671 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;
1672 1857
1673 /* how long to pause the thrower. Higher values mean less pause */ 1858 /* how long to pause the thrower. Higher values mean less pause */
1674 pause_f = ((2*eff_str)/3)+20+skill->level; 1859 pause_f = ((2 * eff_str) / 3) + 20 + skill->level;
1675 1860
1676 /* Put a lower limit on this */ 1861 /* Put a lower limit on this */
1677 if (pause_f < 10) pause_f=10; 1862 if (pause_f < 10)
1678 if (pause_f > 100) pause_f=100; 1863 pause_f = 10;
1864 if (pause_f > 100)
1865 pause_f = 100;
1679 1866
1680 /* Changed in 0.94.2 - the calculation before was really goofy. 1867 /* Changed in 0.94.2 - the calculation before was really goofy.
1681 * 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
1682 * speed 0.5 1869 * speed 0.5
1683 */ 1870 */
1684 op->speed_left -= 50 / pause_f; 1871 op->speed_left -= 50 / pause_f;
1685 1872
1686 update_ob_speed(throw_ob); 1873 update_ob_speed (throw_ob);
1687 throw_ob->speed_left = 0; 1874 throw_ob->speed_left = 0;
1688 throw_ob->map = part->map; 1875 throw_ob->map = part->map;
1689 1876
1690 throw_ob->move_type = MOVE_FLY_LOW; 1877 throw_ob->move_type = MOVE_FLY_LOW;
1691 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK; 1878 throw_ob->move_on = MOVE_FLY_LOW | MOVE_WALK;
1692 1879
1693#if 0 1880#if 0
1694 /* need to put in a good sound for this */ 1881 /* need to put in a good sound for this */
1695 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);
1696#endif 1883#endif
1884
1697/* 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) */
1698 execute_event(throw_ob, EVENT_THROW,op,NULL,NULL,SCRIPT_FIX_ACTIVATOR); 1886 INVOKE_OBJECT (THROW, throw_ob, ARG_OBJECT (op));
1699#ifdef DEBUG_THROW 1887#ifdef DEBUG_THROW
1700 LOG(llevDebug," pause_f=%d \n",pause_f); 1888 LOG (llevDebug, " pause_f=%d \n", pause_f);
1701 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",
1702 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);
1703 throw_ob->last_sp,throw_ob->speed,throw_ob->stats.food);
1704 LOG(llevDebug,"inserting tossitem (%d) into map\n",throw_ob->count); 1891 LOG (llevDebug, "inserting tossitem (%d) into map\n", throw_ob->count);
1705#endif 1892#endif
1706 tag = throw_ob->count;
1707 insert_ob_in_map(throw_ob,part->map,op,0); 1893 insert_ob_in_map (throw_ob, part->map, op, 0);
1708 if (!was_destroyed (throw_ob, tag)) 1894
1895 if (!throw_ob->destroyed ())
1709 move_arrow(throw_ob); 1896 move_arrow (throw_ob);
1897
1710 return 1; 1898 return 1;
1711} 1899}
1712 1900
1901int
1713int 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{
1714 object *throw_ob; 1904 object *throw_ob;
1715 1905
1716 if(op->type==PLAYER) 1906 if (op->type == PLAYER)
1717 throw_ob = find_throw_ob(op,params); 1907 throw_ob = find_throw_ob (op, params);
1718 else 1908 else
1719 throw_ob = find_mon_throw_ob(op); 1909 throw_ob = find_mon_throw_ob (op);
1720 1910
1721 return do_throw(op,part, throw_ob,dir, skill); 1911 return do_throw (op, part, throw_ob, dir, skill);
1722} 1912}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines