Crossfire Server, Branches 1.12  R18729
shop_mat.c
Go to the documentation of this file.
1 /*
2  CrossFire, A Multiplayer game for X-windows
3 
4  Copyright (C) 2007 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 
27 #include <global.h>
28 #include <ob_methods.h>
29 #include <ob_types.h>
30 #include <sounds.h>
31 #include <sproto.h>
32 
33 static method_ret shop_mat_type_move_on(ob_methods *context, object *trap, object *victim, object *originator);
34 
38 void init_type_shop_mat(void) {
40 }
41 
50 static method_ret shop_mat_type_move_on(ob_methods *context, object *trap, object *victim, object *originator) {
51  int rv = 0;
52  double opinion;
53  object *tmp, *next;
54 
55  if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
56  return METHOD_OK;
57 
58  SET_FLAG(victim, FLAG_NO_APPLY); /* prevent loops */
59 
60  if (victim->type != PLAYER) {
61  /* Remove all the unpaid objects that may be carried here.
62  * This could be pets or monsters that are somehow in
63  * the shop.
64  */
65  for (tmp = victim->inv; tmp; tmp = next) {
66  next = tmp->below;
67  if (QUERY_FLAG(tmp, FLAG_UNPAID)) {
68  int i = find_free_spot(tmp, victim->map, victim->x, victim->y, 1, 9);
69  remove_ob(tmp);
70  if (i == -1)
71  i = 0;
72  tmp->map = victim->map;
73  tmp->x = victim->x+freearr_x[i];
74  tmp->y = victim->y+freearr_y[i];
75  insert_ob_in_map(tmp, victim->map, victim, 0);
76  }
77  }
78 
79  /* Don't teleport things like spell effects */
80  if (QUERY_FLAG(victim, FLAG_NO_PICK))
81  goto leave;
82 
83  /* unpaid objects, or non living objects, can't transfer by
84  * shop mats. Instead, put it on a nearby space.
85  */
86  if (QUERY_FLAG(victim, FLAG_UNPAID) || !QUERY_FLAG(victim, FLAG_ALIVE)) {
87  /* Somebody dropped an unpaid item, just move to an adjacent place. */
88  int i = find_free_spot(victim, victim->map, victim->x, victim->y, 1, 9);
89  if (i != -1) {
90  rv = transfer_ob(victim, victim->x+freearr_x[i], victim->y+freearr_y[i], 0, trap);
91  }
92  goto leave;
93  }
94  rv = teleport(trap, SHOP_MAT, victim);
95  /* immediate block below is only used for players */
96  } else if (can_pay(victim)) {
97  get_payment(victim, victim->inv);
98  rv = teleport(trap, SHOP_MAT, victim);
99  if (trap->msg) {
101  trap->msg, NULL);
102  }
103  /* This check below is a bit simplistic - generally it should be correct,
104  * but there is never a guarantee that the bottom space on the map is
105  * actually the shop floor.
106  */
107  else if (!rv && !is_in_shop(victim)) {
108  opinion = shopkeeper_approval(victim->map, victim);
109  if (opinion > 0.9)
111  "The shopkeeper gives you a friendly wave.", NULL);
112  else if (opinion > 0.75)
114  "The shopkeeper waves to you.", NULL);
115  else if (opinion > 0.5)
117  "The shopkeeper ignores you.", NULL);
118  else
120  "The shopkeeper glares at you with contempt.", NULL);
121  }
122  } else {
123  /* if we get here, a player tried to leave a shop but was not able
124  * to afford the items he has. We try to move the player so that
125  * they are not on the mat anymore
126  */
127  int i = find_free_spot(victim, victim->map, victim->x, victim->y, 1, 9);
128  if (i == -1)
129  LOG(llevError, "Internal shop-mat problem.\n");
130  else {
131  remove_ob(victim);
132  victim->x += freearr_x[i];
133  victim->y += freearr_y[i];
134  rv = insert_ob_in_map(victim, victim->map, trap, 0) == NULL;
135  esrv_map_scroll(&victim->contr->socket, freearr_x[i], freearr_y[i]);
136  victim->contr->socket.update_look = 1;
137  victim->contr->socket.look_position = 0;
138  }
139  }
140  CLEAR_FLAG(victim, FLAG_NO_APPLY);
141 leave:
142  common_post_ob_move_on(trap, victim, originator);
143  return METHOD_OK;
144 }
#define FLAG_UNPAID
Definition: define.h:532
int is_in_shop(object *ob)
Definition: shop.c:1414
int teleport(object *teleporter, uint8 tele_type, object *user)
Definition: move.c:244
void leave(player *pl, int draw_exit)
Definition: server.c:1234
#define SET_FLAG(xyz, p)
Definition: define.h:510
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:51
#define METHOD_ERROR
Definition: ob_methods.h:44
socket_struct socket
Definition: player.h:148
short freearr_x[SIZEOFFREE]
Definition: object.c:75
void draw_ext_info(int flags, int pri, const object *pl, uint8 type, uint8 subtype, const char *message, const char *oldmessage)
Definition: standalone.c:171
sint16 x
Definition: object.h:179
#define PLAYER
Definition: define.h:113
short freearr_y[SIZEOFFREE]
Definition: object.c:81
char method_ret
Definition: ob_methods.h:41
void remove_ob(object *op)
Definition: object.c:1515
#define FLAG_ALIVE
Definition: define.h:526
void init_type_shop_mat(void)
Definition: shop_mat.c:38
#define MSG_TYPE_SHOP_MISC
Definition: newclient.h:431
#define MSG_TYPE_SHOP
Definition: newclient.h:325
void register_move_on(int ob_type, move_on_func method)
Definition: ob_types.c:106
#define METHOD_OK
Definition: ob_methods.h:42
struct mapdef * map
Definition: object.h:155
struct obj * below
Definition: object.h:145
double shopkeeper_approval(const mapstruct *map, const object *player)
Definition: shop.c:1243
sint16 y
Definition: object.h:179
struct pl * contr
Definition: object.h:134
#define SHOP_MAT
Definition: define.h:231
#define QUERY_FLAG(xyz, p)
Definition: define.h:514
#define CLEAR_FLAG(xyz, p)
Definition: define.h:512
#define MSG_TYPE_APPLY
Definition: newclient.h:330
int can_pay(object *pl)
Definition: shop.c:938
object * insert_ob_in_map(object *op, mapstruct *m, object *originator, int flag)
Definition: object.c:1992
void esrv_map_scroll(socket_struct *ns, int dx, int dy)
Definition: request.c:1432
uint16 look_position
Definition: newserver.h:142
#define FLAG_NO_APPLY
Definition: define.h:598
void common_post_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.c:88
#define MSG_TYPE_APPLY_SUCCESS
Definition: newclient.h:518
uint32 update_look
Definition: newserver.h:131
int get_payment(object *pl, object *op)
Definition: shop.c:992
const char * msg
Definition: object.h:175
int find_free_spot(const object *ob, mapstruct *m, int x, int y, int start, int stop)
Definition: object.c:3200
static method_ret shop_mat_type_move_on(ob_methods *context, object *trap, object *victim, object *originator)
Definition: shop_mat.c:50
struct obj * inv
Definition: object.h:148
#define NDI_UNIQUE
Definition: newclient.h:219
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:63
int transfer_ob(object *op, int x, int y, int randomly, object *originator)
Definition: move.c:197
#define FLAG_NO_PICK
Definition: define.h:535
uint8 type
Definition: object.h:189