Crossfire Server, Trunk  1.75.0
shop_mat.cpp
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 "shop.h"
31 #include "sounds.h"
32 #include "sproto.h"
33 
34 static method_ret shop_mat_type_move_on(object *trap, object *victim, object *originator);
35 
39 void init_type_shop_mat(void) {
41 }
42 
50 static method_ret shop_mat_type_move_on(object *trap, object *victim, object *originator) {
51  int rv = 0;
52  double opinion;
53 
54  if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR)
55  return METHOD_OK;
56 
57  SET_FLAG(victim, FLAG_NO_APPLY); /* prevent loops */
58 
59  if (victim->type != PLAYER) {
60  /* Remove all the unpaid objects that may be carried here.
61  * This could be pets or monsters that are somehow in
62  * the shop.
63  */
64  FOR_INV_PREPARE(victim, tmp) {
65  if (QUERY_FLAG(tmp, FLAG_UNPAID)) {
66  int i = object_find_free_spot(tmp, victim->map, victim->x, victim->y, 1, 9);
67  object_remove(tmp);
68  if (i == -1)
69  i = 0;
70  object_insert_in_map_at(tmp, victim->map, victim, 0, victim->x+freearr_x[i], victim->y+freearr_y[i]);
71  }
72  } FOR_INV_FINISH();
73 
74  /* Don't teleport things like spell effects */
75  if (QUERY_FLAG(victim, FLAG_NO_PICK))
76  goto leave;
77 
78  /* unpaid objects, or non living objects, can't transfer by
79  * shop mats. Instead, put it on a nearby space.
80  */
81  if (QUERY_FLAG(victim, FLAG_UNPAID) || !QUERY_FLAG(victim, FLAG_ALIVE)) {
82  /* Somebody dropped an unpaid item, just move to an adjacent place. */
83  int i = object_find_free_spot(victim, victim->map, victim->x, victim->y, 1, 9);
84  if (i != -1) {
85  rv = transfer_ob(victim, victim->x+freearr_x[i], victim->y+freearr_y[i], 0, trap);
86  }
87  goto leave;
88  }
89  rv = teleport(trap, SHOP_MAT, victim);
90  /* immediate block below is only used for players */
91  } else if (can_pay(victim)) {
92  shop_pay_unpaid(victim, victim->inv);
93  rv = teleport(trap, SHOP_MAT, victim);
94  if (trap->msg) {
96  trap->msg);
97  }
98  /* This check below is a bit simplistic - generally it should be correct,
99  * but there is never a guarantee that the bottom space on the map is
100  * actually the shop floor.
101  */
102  else if (!rv && !shop_contains(victim)) {
103  opinion = shop_approval(victim->map, victim);
104  if (opinion > 0.9)
106  "The shopkeeper gives you a friendly wave.");
107  else if (opinion > 0.75)
109  "The shopkeeper waves to you.");
110  else if (opinion > 0.5)
112  "The shopkeeper ignores you.");
113  else
115  "The shopkeeper glares at you with contempt.");
116  }
117  } else {
118  /* if we get here, a player tried to leave a shop but was not able
119  * to afford the items he has. We try to move the player so that
120  * they are not on the mat anymore
121  */
122  int i = object_find_free_spot(victim, victim->map, victim->x, victim->y, 1, 9);
123  if (i == -1)
124  LOG(llevError, "Internal shop-mat problem.\n");
125  else {
126  object_remove(victim);
127  rv = object_insert_in_map_at(victim, victim->map, trap, 0, victim->x+freearr_x[i], victim->y+freearr_y[i]) == NULL;
128  esrv_map_scroll(victim->contr->socket, freearr_x[i], freearr_y[i]);
129  victim->contr->socket->update_look = 1;
130  victim->contr->socket->look_position = 0;
131  }
132  }
133  CLEAR_FLAG(victim, FLAG_NO_APPLY);
134 leave:
135  common_post_ob_move_on(trap, victim, originator);
136  return METHOD_OK;
137 }
PLAYER
@ PLAYER
Definition: object.h:112
global.h
llevError
@ llevError
Error, serious thing.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:58
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
esrv_map_scroll
void esrv_map_scroll(socket_struct *ns, int dx, int dy)
Definition: request.cpp:1708
object::inv
object * inv
Pointer to the first object in the inventory.
Definition: object.h:298
socket_struct::look_position
uint16_t look_position
Start of drawing of look window.
Definition: newserver.h:114
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
METHOD_OK
#define METHOD_OK
Definition: ob_methods.h:15
object::x
int16_t x
Definition: object.h:335
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
register_move_on
void register_move_on(int ob_type, move_on_func method)
Registers the move_on method for the given type.
Definition: ob_types.cpp:89
MSG_TYPE_SHOP_MISC
#define MSG_TYPE_SHOP_MISC
Random messages.
Definition: newclient.h:516
FLAG_NO_PICK
#define FLAG_NO_PICK
Object can't be picked up.
Definition: define.h:239
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
socket_struct::update_look
uint32_t update_look
If true, we need to send the look window.
Definition: newserver.h:104
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
object::contr
struct player * contr
Pointer to the player which control this object.
Definition: object.h:284
teleport
int teleport(object *teleporter, uint8_t tele_type, object *user)
Teleport an item around a nearby random teleporter of specified type.
Definition: move.cpp:204
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
common_pre_ob_move_on
method_ret common_pre_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.cpp:35
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
shop_pay_unpaid
int shop_pay_unpaid(object *pl, object *op)
Pay for each unpaid item carried by a player, including those inside containers.
Definition: shop.cpp:949
leave
void leave(player *pl, int draw_exit)
Player logs out, or was disconnected.
Definition: server.cpp:1303
FOR_INV_FINISH
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
Definition: define.h:671
sproto.h
MSG_TYPE_SHOP
#define MSG_TYPE_SHOP
Definition: newclient.h:406
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
SHOP_MAT
@ SHOP_MAT
Definition: object.h:189
transfer_ob
int transfer_ob(object *op, int x, int y, int randomly, object *originator)
Move an object (even linked objects) to another spot on the same map.
Definition: move.cpp:163
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
shop_mat_type_move_on
static method_ret shop_mat_type_move_on(object *trap, object *victim, object *originator)
Move on this Shop Mat object.
Definition: shop_mat.cpp:50
shop.h
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
object::msg
sstring msg
If this is a book/sign/magic mouth/etc.
Definition: object.h:330
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
can_pay
int can_pay(object *pl)
Checks all unpaid items in op's inventory, adds up all the money they have, and checks that they can ...
Definition: shop.cpp:841
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
shop_approval
double shop_approval(const mapstruct *map, const object *player)
Return the approval ratio for a shop for a given player.
Definition: shop.cpp:1135
FLAG_UNPAID
#define FLAG_UNPAID
Object hasn't been paid for yet.
Definition: define.h:236
METHOD_ERROR
#define METHOD_ERROR
Definition: ob_methods.h:17
init_type_shop_mat
void init_type_shop_mat(void)
Initializer for the SHOP_MAT object type.
Definition: shop_mat.cpp:39
player::socket
socket_struct * socket
Socket information for this player.
Definition: player.h:107
ob_methods.h
freearr_x
short freearr_x[SIZEOFFREE]
X offset when searching around a spot.
Definition: object.cpp:299
shop_contains
bool shop_contains(object *ob)
Check if an object is in a shop.
Definition: shop.cpp:1300
MSG_TYPE_APPLY
#define MSG_TYPE_APPLY
Applying objects.
Definition: newclient.h:411
common_post_ob_move_on
void common_post_ob_move_on(object *trap, object *victim, object *originator)
Definition: common_apply.cpp:67
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
Definition: define.h:664
FLAG_NO_APPLY
#define FLAG_NO_APPLY
Avoids step_on/fly_on to this object.
Definition: define.h:301