Crossfire Server, Trunk
mimic.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2018 Mark Wedel & Crossfire Development Team
5  Copyright (C) 1992 Frank Tore Johansen
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  The authors can be reached via e-mail at crossfire-devel@real-time.com
22 */
23 
30 #include <global.h>
31 #include <ob_methods.h>
32 #include <ob_types.h>
33 #include <sounds.h>
34 #include <sproto.h>
35 #include <string.h>
36 #include <stdlib.h>
37 
38 static method_ret mimic_type_apply(object *op, object *applier, int aflags);
39 
43 void init_type_mimic(void) {
45 }
46 
47 static inline const char *object_try_get_value(object *op, const char *key) {
48  const char *val = object_get_value(op, key);
49  return val ? val : "0";
50 }
51 
61 static method_ret mimic_type_apply(object *op, object *applier, int aflags) {
62  (void)aflags;
63  if (applier->type == PLAYER) {
64 
65  if (op->env) {
66  char name[MAX_BUF];
67  query_name(op, name, sizeof(name));
68  object *env = op->env;
69  if (!env->map) {
70  // Not supposed to happen, since mimics can't be put into other containers
71  draw_ext_info_format(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, "You can't seem to open the %s.", name);
72  return METHOD_OK;
73  }
75  op->type = MONSTER;
76  int dir = object_find_free_spot(op, env->map, env->x, env->y, 1, SIZEOFFREE);
77  if (dir == -1) {
79  op->type = MIMIC;
80  draw_ext_info_format(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE, "You can't seem to open the %s.", name);
81  return METHOD_OK;
82  }
83  op = object_insert_in_map_at(op, env->map, NULL, 0, env->x + freearr_x[dir], env->y + freearr_y[dir]);
84  draw_ext_info_format(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS, "The %s suddenly escapes!", name);
85  }
86 
87  draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS, "Ah! It's alive!");
88  /* We become a monster */
89  op->type = MONSTER;
90  /* We are animated, too, assuming we have a face right now. */
91  if (op->face)
92  {
93  char anim_name_buf[128];
94  int anim_name_len = strlen(op->face->name);
95  strncpy(anim_name_buf, op->face->name, 128);
96  // Remove the .11x from the end of the face name.
97  anim_name_buf[anim_name_len-4] = '\0';
98  strncat(anim_name_buf, "_mimic", 128-anim_name_len+4);
99  op->animation = find_animation(anim_name_buf);
101  }
104  // If we don't have a level set, use the map difficulty
105  if (!op->level)
106  op->level = op->map ? op->map->difficulty : 0;
107  // Set the scalable stats based off the level given to the mimic at load.
108  int level = op->level;
109  op->stats.hp = op->stats.maxhp = op->stats.maxhp + (int16_t)(atof(object_try_get_value(op, "hp_per_level")) * level);
110  op->stats.dam = op->stats.dam + (int16_t)(atof(object_try_get_value(op, "dam_per_level")) * level);
111  op->stats.ac = op->stats.ac + (int8_t)(atof(object_try_get_value(op, "ac_per_level")) * level);
112  op->stats.wc = op->stats.wc + (int8_t)(atof(object_try_get_value(op, "wc_per_level")) * level);
113  op->stats.exp = op->stats.exp + (int64_t)(atof(object_try_get_value(op, "xp_per_level")) * level);
114  op->speed = FABS(op->speed) + atof(object_try_get_value(op, "speed_per_level")) * level;
115  // Set enemy to the triggerer.
116  op->enemy = applier;
117  // TODO: Should this be able to be set dynamically?
118  FREE_AND_COPY(op->name, "mimic");
119  return METHOD_OK;
120  }
121  return METHOD_UNHANDLED;
122 }
MIMIC
@ MIMIC
Definition: object.h:249
PLAYER
@ PLAYER
Definition: object.h:107
global.h
object_remove
void object_remove(object *op)
Definition: object.c:1819
MONSTER
@ MONSTER
Definition: object.h:200
FABS
#define FABS(x)
Definition: define.h:22
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
METHOD_OK
#define METHOD_OK
Definition: ob_methods.h:15
mimic_type_apply
static method_ret mimic_type_apply(object *op, object *applier, int aflags)
Definition: mimic.c:61
freearr_x
short freearr_x[SIZEOFFREE]
Definition: object.c:299
freearr_y
short freearr_y[SIZEOFFREE]
Definition: object.c:305
FLAG_ALIVE
#define FLAG_ALIVE
Definition: define.h:230
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4317
METHOD_UNHANDLED
#define METHOD_UNHANDLED
Definition: ob_methods.h:16
MSG_TYPE_APPLY_SUCCESS
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:603
query_name
void query_name(const object *op, char *buf, size_t size)
Definition: item.c:585
FREE_AND_COPY
#define FREE_AND_COPY(sv, nv)
Definition: global.h:201
sproto.h
nlohmann::detail::void
j template void())
Definition: json.hpp:4099
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
SIZEOFFREE
#define SIZEOFFREE
Definition: define.h:155
env
static std::shared_ptr< inja::Environment > env
Definition: mapper.cpp:2216
MAX_BUF
#define MAX_BUF
Definition: define.h:35
register_apply
void register_apply(int ob_type, apply_func method)
Definition: ob_types.c:62
method_ret
char method_ret
Definition: ob_methods.h:14
ob_types.h
sounds.h
obj::type
uint8_t type
Definition: object.h:343
NDI_UNIQUE
#define NDI_UNIQUE
Definition: newclient.h:262
init_type_mimic
void init_type_mimic(void)
Definition: mimic.c:43
give.op
op
Definition: give.py:33
object_find_free_spot
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3530
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2833
find_animation
Animations * find_animation(const char *name)
Definition: assets.cpp:296
MSG_TYPE_APPLY_FAILURE
#define MSG_TYPE_APPLY_FAILURE
Definition: newclient.h:604
castle_read.key
key
Definition: castle_read.py:64
FLAG_ANIMATE
#define FLAG_ANIMATE
Definition: define.h:242
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:2080
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:309
level
int level
Definition: readable.c:1608
ob_methods.h
object_try_get_value
static const char * object_try_get_value(object *op, const char *key)
Definition: mimic.c:47
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Definition: newclient.h:408
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:319
give.name
name
Definition: give.py:27
level
Definition: level.py:1