Atrinik Server  4.0
rod.c
Go to the documentation of this file.
1 /*************************************************************************
2  * Atrinik, a Multiplayer Online Role Playing Game *
3  * *
4  * Copyright (C) 2009-2014 Alex Tokar and Atrinik Development Team *
5  * *
6  * Fork from Crossfire (Multiplayer game for X-windows). *
7  * *
8  * This program is free software; you can redistribute it and/or modify *
9  * it under the terms of the GNU General Public License as published by *
10  * the Free Software Foundation; either version 2 of the License, or *
11  * (at your option) any later version. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this program; if not, write to the Free Software *
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
21  * *
22  * The author can be reached at admin@atrinik.org *
23  ************************************************************************/
24 
32 #include <global.h>
33 #include <player.h>
34 #include <object.h>
35 #include <object_methods.h>
36 
38 
40 static void
41 process_func (object *op)
42 {
43  HARD_ASSERT(op != NULL);
44 
45  if (op->stats.hp < op->stats.maxhp) {
46  op->stats.hp++;
47  }
48 }
49 
51 static int
52 ranged_fire_func (object *op, object *shooter, int dir, double *delay)
53 {
54  HARD_ASSERT(op != NULL);
55  HARD_ASSERT(shooter != NULL);
56 
57  if (op->stats.sp < 0 || op->stats.sp >= NROFREALSPELLS) {
58  draw_info_format(COLOR_WHITE, shooter,
59  "The %s is broken.",
60  op->name);
62  }
63 
64  /* If the device level is higher than player's magic skill, don't allow
65  * using the device. */
66  if (shooter->type == PLAYER &&
67  op->level > (CONTR(shooter)->skill_ptr[SK_WIZARDRY_SPELLS]->level +
69  draw_info_format(COLOR_WHITE, shooter,
70  "The %s is impossible to handle for you.",
71  op->name);
73  }
74 
75  if (op->stats.maxhp && op->stats.hp <= 0) {
76  play_sound_player_only(CONTR(shooter),
77  CMD_SOUND_EFFECT,
78  "rod.ogg",
79  0,
80  0,
81  0,
82  0);
83  draw_info_format(COLOR_WHITE, shooter,
84  "The %s whines for a while, but nothing happens.",
85  op->name);
87  }
88 
89  if (cast_spell(shooter, op, dir, op->stats.sp, 0, CAST_ROD, NULL)) {
91 
92  if (op->stats.maxhp != 0) {
93  op->stats.hp--;
94  }
95  }
96 
97  if (delay != NULL) {
98  *delay = op->last_grace;
99  }
100 
101  return OBJECT_METHOD_OK;
102 }
103 
105 static int
107  object **ret,
108  int difficulty,
109  treasure_affinity_t *affinity,
110  int flags)
111 {
112  HARD_ASSERT(op != NULL);
113  HARD_ASSERT(difficulty > 0);
114 
115  /* Avoid processing if the item is already special. */
116  if (process_treasure_is_special(op)) {
118  }
119 
120  op->stats.sp = spell_get_random(difficulty, SPELL_USE_ROD);
121  if (op->stats.sp == SP_NO_SPELL) {
122  log_error("Failed to generate a spell for rod: %s",
123  object_get_str(op));
124  object_remove(op, 0);
125  object_destroy(op);
126  return OBJECT_METHOD_ERROR;
127  }
128 
130 
131  if (op->stats.maxhp != 0) {
132  op->stats.maxhp += rndm(0, op->stats.maxhp);
133  }
134 
135  op->stats.hp = op->stats.maxhp;
136 
137  /* Calculate the level. Essentially -20 below the difficulty at worst, or
138  * +15 above the difficulty at best. */
139  int level = difficulty - 20 + rndm(0, 15);
140  level = MIN(MAX(level, 1), MAXLEVEL);
141  op->level = level;
142 
143  return OBJECT_METHOD_OK;
144 }
145 
150 {
151  OBJECT_METHODS(ROD)->apply_func = object_apply_item;
152  OBJECT_METHODS(ROD)->process_func = process_func;
153  OBJECT_METHODS(ROD)->ranged_fire_func = ranged_fire_func;
154  OBJECT_METHODS(ROD)->process_treasure_func = process_treasure_func;
155 }
void object_destroy(object *ob)
Definition: object.c:1441
#define NROFREALSPELLS
Definition: define.h:664
#define OBJECT_METHOD_ERROR
#define PLAYER
Definition: define.h:122
int16_t sp
Definition: living.h:78
int8_t magic_devices_level
Definition: global.h:408
void object_remove(object *op, int flags)
Definition: object.c:1623
int32_t hp
Definition: living.h:72
int cast_spell(object *op, object *caster, int dir, int type, int ability, int item, const char *stringarg)
Definition: spell_util.c:192
#define FLAG_BEEN_APPLIED
Definition: define.h:934
int32_t maxhp
Definition: living.h:75
const char * object_get_str(const object *op)
Definition: object.c:3151
void play_sound_player_only(player *pl, int type, const char *filename, int x, int y, int loop, int volume)
Definition: sounds.c:66
#define SP_NO_SPELL
Definition: spells.h:202
const char * name
Definition: object.h:168
#define SET_FLAG(xyz, p)
Definition: define.h:741
int16_t last_grace
Definition: object.h:316
static void process_func(object *op)
Definition: rod.c:41
#define ROD
Definition: define.h:130
#define OBJECT_METHOD_UNHANDLED
#define SPELL_USE_ROD
Definition: spells.h:99
#define CAST_ROD
Definition: spells.h:279
static int process_treasure_func(object *op, object **ret, int difficulty, treasure_affinity_t *affinity, int flags)
Definition: rod.c:106
struct settings_struct settings
Definition: init.c:55
#define MAXLEVEL
Definition: global.h:221
bool process_treasure_is_special(object *op)
int object_apply_item(object *op, object *applier, int aflags)
Definition: apply.c:110
OBJECT_TYPE_INIT_DEFINE(rod)
Definition: rod.c:149
living stats
Definition: object.h:481
uint8_t type
Definition: object.h:360
#define OBJECT_METHODS(type)
static int ranged_fire_func(object *op, object *shooter, int dir, double *delay)
Definition: rod.c:52
int spell_get_random(int level, int flags)
Definition: spell_util.c:1230
#define OBJECT_METHOD_OK
#define FLAG_IS_MAGICAL
Definition: define.h:1129
int8_t level
Definition: object.h:347