Atrinik Server  4.0
rune.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 #include <disease.h>
37 #include <rune.h>
38 
47 void
48 rune_spring (object *op, object *victim)
49 {
50  HARD_ASSERT(op != NULL);
51  HARD_ASSERT(victim != NULL);
52 
53  if (op->stats.hp == 0) {
54  return;
55  }
56 
57  /* Only living objects can trigger runes that do direct damage. */
58  if (!IS_LIVE(victim) && op->stats.sp == -1) {
59  return;
60  }
61 
62  if (op->msg != NULL) {
63  draw_info(COLOR_WHITE, victim, op->msg);
64  }
65 
66  object *env = object_get_env(op);
67  trap_show(op, env);
68 
69  if (victim->type == PLAYER) {
70  CONTR(victim)->stat_traps_sprung++;
71  }
72 
73  /* Direct damage. */
74  if (op->stats.sp == -1) {
75  OBJECTS_DESTROYED_BEGIN(op, victim) {
76  int dam = op->stats.dam * (LEVEL_DAMAGE(op->level) * 0.925f);
77  attack_hit(victim, op, dam);
78 
79  if (!OBJECTS_DESTROYED(victim)) {
80  if (op->randomitems != NULL) {
81  int level = op->level;
82  if (level == 0) {
83  level = env->map->difficulty;
84  }
85 
86  treasure_generate(op->randomitems, op, level, 0);
87  }
88 
89  FOR_INV_PREPARE(op, tmp) {
90  if (tmp->type != DISEASE) {
91  continue;
92  }
93 
94  disease_infect(tmp, victim, 1);
95  object_remove(tmp, 0);
96  object_destroy(tmp);
97  } FOR_INV_FINISH();
98  }
99 
100  if (OBJECTS_DESTROYED(op)) {
101  return;
102  }
104  } else {
105  /* Spell. */
106  cast_spell(env,
107  op,
108  op->stats.maxsp,
109  op->stats.sp,
110  1,
111  CAST_NORMAL,
112  NULL);
113  }
114 
115  /* Decrement detonation count and see if it's the last one, but only
116  * if the count is not -1 already (infinite). */
117  if (op->stats.hp != -1 && --op->stats.hp == 0) {
118  /* Make the trap impotent */
119  op->type = MISC_OBJECT;
120  CLEAR_FLAG(op, FLAG_FLY_ON);
123  /* Make it stick around until its spells are gone */
124  op->stats.food = 20;
126  op->speed = op->speed_left = 1.0;
128  /* Clear trapped flag. */
129  set_trapped_flag(env);
130  }
131 }
132 
134 static int
135 move_on_func (object *op, object *victim, object *originator, int state)
136 {
137  HARD_ASSERT(op != NULL);
138  HARD_ASSERT(victim != NULL);
139 
140  rune_spring(op, victim);
141  return OBJECT_METHOD_OK;
142 }
143 
145 static int
147  object **ret,
148  int difficulty,
149  treasure_affinity_t *affinity,
150  int flags)
151 {
152  HARD_ASSERT(op != NULL);
153  HARD_ASSERT(difficulty > 0);
154 
155  int off = (int) ((float) difficulty * 0.2f);
156  int level = rndm(difficulty - off, difficulty + off);
157  level = MAX(1, MIN(level, MAXLEVEL));
158  int hide = rndm(0, 19) + rndm(difficulty - off, difficulty + off);
159  hide = MAX(1, MIN(hide, INT8_MAX));
160 
161  op->level = level;
162  op->stats.Int = hide;
163 
164  return OBJECT_METHOD_OK;
165 }
166 
171 {
172  OBJECT_METHODS(RUNE)->move_on_func = move_on_func;
173  OBJECT_METHODS(RUNE)->process_treasure_func = process_treasure_func;
174 }
void object_destroy(object *ob)
Definition: object.c:1441
object * object_get_env(object *op)
Definition: object.c:631
#define DISEASE
Definition: define.h:538
void treasure_generate(treasure_list_t *treasure_list, object *op, int difficulty, int flags)
Definition: treasure.c:1641
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:1691
#define FOR_INV_FINISH()
Definition: define.h:1698
double speed_left
Definition: object.h:472
struct treasure_list * randomitems
Definition: object.h:231
#define FLAG_FLY_ON
Definition: define.h:968
#define MISC_OBJECT
Definition: define.h:349
#define IS_LIVE(op)
Definition: define.h:841
#define PLAYER
Definition: define.h:122
int16_t sp
Definition: living.h:78
#define OBJECTS_DESTROYED_BEGIN(...)
Definition: object.h:765
static int move_on_func(object *op, object *victim, object *originator, int state)
Definition: rune.c:135
int8_t Int
Definition: living.h:112
void object_remove(object *op, int flags)
Definition: object.c:1623
int16_t maxsp
Definition: living.h:81
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
static int process_treasure_func(object *op, object **ret, int difficulty, treasure_affinity_t *affinity, int flags)
Definition: rune.c:146
struct mapdef * map
Definition: object.h:139
int16_t dam
Definition: living.h:87
#define SET_FLAG(xyz, p)
Definition: define.h:741
#define OBJECTS_DESTROYED(obj)
Definition: object.h:811
#define FLAG_IS_USED_UP
Definition: define.h:976
double speed
Definition: object.h:469
OBJECT_TYPE_INIT_DEFINE(rune)
Definition: rune.c:170
#define MAXLEVEL
Definition: global.h:221
int difficulty
Definition: map.h:650
#define LEVEL_DAMAGE(level)
Definition: living.h:61
#define OBJECTS_DESTROYED_END()
Definition: object.h:816
living stats
Definition: object.h:481
int attack_hit(object *op, object *hitter, int dam)
Definition: attack.c:669
uint8_t type
Definition: object.h:360
#define CLEAR_FLAG(xyz, p)
Definition: define.h:751
#define OBJECT_METHODS(type)
const char * msg
Definition: object.h:183
void rune_spring(object *op, object *victim)
Definition: rune.c:48
#define RUNE
Definition: define.h:522
#define OBJECT_METHOD_OK
void set_trapped_flag(object *op)
Definition: item.c:1386
#define FLAG_WALK_ON
Definition: define.h:904
int trap_show(object *trap, object *where)
Definition: rune.c:73
void object_update_speed(object *op)
Definition: object.c:1043
#define CAST_NORMAL
Definition: spells.h:275
int8_t level
Definition: object.h:347
#define FREE_AND_CLEAR_HASH2(_nv_)
Definition: global.h:162
int16_t food
Definition: living.h:84
bool disease_infect(object *op, object *victim, bool force)
Definition: disease.c:396