Crossfire Server, Trunk  1.75.0
mimic.cpp
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  }
74  object_remove(op);
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);
100  SET_FLAG(op, FLAG_ANIMATE);
101  }
102  SET_FLAG(op, FLAG_ALIVE);
103  SET_FLAG(op, FLAG_MONSTER);
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 }
Face::name
sstring name
Face name, as used by archetypes and such.
Definition: face.h:19
living::exp
int64_t exp
Experience.
Definition: living.h:47
MIMIC
@ MIMIC
Definition: object.h:254
PLAYER
@ PLAYER
Definition: object.h:112
global.h
living::maxhp
int16_t maxhp
Max hit points.
Definition: living.h:41
MONSTER
@ MONSTER
A real, living creature.
Definition: object.h:205
init_type_mimic
void init_type_mimic(void)
Initializer for MIMIC type.
Definition: mimic.cpp:43
FABS
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
mapstruct::difficulty
uint16_t difficulty
What level the player should be to play here.
Definition: map.h:333
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
object_try_get_value
static const char * object_try_get_value(object *op, const char *key)
Definition: mimic.cpp:47
register_apply
void register_apply(int ob_type, apply_func method)
Registers the apply method for the given type.
Definition: ob_types.cpp:62
object::speed
float speed
Frequency of object 'moves' relative to server tick rate.
Definition: object.h:337
METHOD_OK
#define METHOD_OK
Definition: ob_methods.h:15
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
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,...) PRINTF_ARGS(6
object::enemy
object * enemy
Monster/player to follow even if not closest.
Definition: object.h:391
mimic_type_apply
static method_ret mimic_type_apply(object *op, object *applier, int aflags)
Implementation of mimics This should be usable for any item masquerading as a container (or other ite...
Definition: mimic.cpp:61
object_get_value
const char * object_get_value(const object *op, const char *const key)
Get an extra value by key.
Definition: object.cpp:4346
object::level
int16_t level
Level of creature or object.
Definition: object.h:361
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
Definition: object.cpp:2857
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
draw_ext_info
vs only yadda is in because all tags get reset on the next draw_ext_info In the second since it is all in one draw_ext_info
Definition: media-tags.txt:61
FLAG_ALIVE
#define FLAG_ALIVE
Object can fight (or be fought)
Definition: define.h:230
METHOD_UNHANDLED
#define METHOD_UNHANDLED
Definition: ob_methods.h:16
freearr_y
short freearr_y[SIZEOFFREE]
Y offset when searching around a spot.
Definition: object.cpp:305
MSG_TYPE_APPLY_SUCCESS
#define MSG_TYPE_APPLY_SUCCESS
Was able to apply object.
Definition: newclient.h:606
query_name
void query_name(const object *op, char *buf, size_t size)
Describes an item.
Definition: item.cpp:588
object::face
const Face * face
Face with colors.
Definition: object.h:341
FREE_AND_COPY
#define FREE_AND_COPY(sv, nv)
Release the shared string if not NULL, and make it a reference to nv.
Definition: global.h:206
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
living::dam
int16_t dam
How much damage this object does when hitting.
Definition: living.h:46
sproto.h
object::animation
const Animations * animation
Animation of this item, NULL if not animated.
Definition: object.h:428
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
Definition: object.cpp:2100
FLAG_MONSTER
#define FLAG_MONSTER
Will attack players.
Definition: define.h:245
SIZEOFFREE
#define SIZEOFFREE
Definition: define.h:155
env
static std::shared_ptr< inja::Environment > env
Rendering environment.
Definition: mapper.cpp:2222
MAX_BUF
#define MAX_BUF
Used for all kinds of things.
Definition: define.h:35
living::wc
int8_t wc
Weapon Class, lower WC increases probability of hitting.
Definition: living.h:37
method_ret
char method_ret
Define some standard return values for callbacks which don't need to return any other results.
Definition: ob_methods.h:14
ob_types.h
sounds.h
NDI_UNIQUE
#define NDI_UNIQUE
Print immediately, don't buffer.
Definition: newclient.h:265
object::name
sstring name
The name of the object, obviously...
Definition: object.h:319
object::env
object * env
Pointer to the object which is the environment.
Definition: object.h:301
object_find_free_spot
int object_find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
object_find_free_spot(object, map, x, y, start, stop) will search for a spot at the given map and coo...
Definition: object.cpp:3559
living::ac
int8_t ac
Armor Class, lower AC increases probability of not getting hit.
Definition: living.h:38
find_animation
Animations * find_animation(const char *name)
Definition: assets.cpp:273
level
int level
Definition: readable.cpp:1563
MSG_TYPE_APPLY_FAILURE
#define MSG_TYPE_APPLY_FAILURE
Apply OK, but no/bad result.
Definition: newclient.h:607
FLAG_ANIMATE
#define FLAG_ANIMATE
The object looks at archetype for faces.
Definition: define.h:242
object_remove
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to.
Definition: object.cpp:1833
ob_methods.h
object::stats
living stats
Str, Con, Dex, etc.
Definition: object.h:378
freearr_x
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.cpp:299
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:411
living::hp
int16_t hp
Hit Points.
Definition: living.h:40