Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 CrossFire, A Multiplayer game for X-windows 00003 00004 Copyright (C) 2007 Mark Wedel & Crossfire Development Team 00005 Copyright (C) 1992 Frank Tore Johansen 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 00021 The authors can be reached via e-mail at crossfire-devel@real-time.com 00022 */ 00023 00027 #include <global.h> 00028 #include <ob_methods.h> 00029 #include <ob_types.h> 00030 #include <sounds.h> 00031 #include <sproto.h> 00032 00033 static method_ret shop_mat_type_move_on(ob_methods *context, object *trap, object *victim, object *originator); 00034 00038 void init_type_shop_mat(void) { 00039 register_move_on(SHOP_MAT, shop_mat_type_move_on); 00040 } 00041 00050 static method_ret shop_mat_type_move_on(ob_methods *context, object *trap, object *victim, object *originator) { 00051 int rv = 0; 00052 double opinion; 00053 object *tmp, *next; 00054 00055 if (common_pre_ob_move_on(trap, victim, originator) == METHOD_ERROR) 00056 return METHOD_OK; 00057 00058 SET_FLAG(victim, FLAG_NO_APPLY); /* prevent loops */ 00059 00060 if (victim->type != PLAYER) { 00061 /* Remove all the unpaid objects that may be carried here. 00062 * This could be pets or monsters that are somehow in 00063 * the shop. 00064 */ 00065 for (tmp = victim->inv; tmp; tmp = next) { 00066 next = tmp->below; 00067 if (QUERY_FLAG(tmp, FLAG_UNPAID)) { 00068 int i = find_free_spot(tmp, victim->map, victim->x, victim->y, 1, 9); 00069 remove_ob(tmp); 00070 if (i == -1) 00071 i = 0; 00072 tmp->map = victim->map; 00073 tmp->x = victim->x+freearr_x[i]; 00074 tmp->y = victim->y+freearr_y[i]; 00075 insert_ob_in_map(tmp, victim->map, victim, 0); 00076 } 00077 } 00078 00079 /* Don't teleport things like spell effects */ 00080 if (QUERY_FLAG(victim, FLAG_NO_PICK)) 00081 goto leave; 00082 00083 /* unpaid objects, or non living objects, can't transfer by 00084 * shop mats. Instead, put it on a nearby space. 00085 */ 00086 if (QUERY_FLAG(victim, FLAG_UNPAID) || !QUERY_FLAG(victim, FLAG_ALIVE)) { 00087 /* Somebody dropped an unpaid item, just move to an adjacent place. */ 00088 int i = find_free_spot(victim, victim->map, victim->x, victim->y, 1, 9); 00089 if (i != -1) { 00090 rv = transfer_ob(victim, victim->x+freearr_x[i], victim->y+freearr_y[i], 0, trap); 00091 } 00092 goto leave; 00093 } 00094 rv = teleport(trap, SHOP_MAT, victim); 00095 /* immediate block below is only used for players */ 00096 } else if (can_pay(victim)) { 00097 get_payment(victim, victim->inv); 00098 rv = teleport(trap, SHOP_MAT, victim); 00099 if (trap->msg) { 00100 draw_ext_info(NDI_UNIQUE, 0, victim, MSG_TYPE_APPLY, MSG_TYPE_APPLY_SUCCESS, 00101 trap->msg, NULL); 00102 } 00103 /* This check below is a bit simplistic - generally it should be correct, 00104 * but there is never a guarantee that the bottom space on the map is 00105 * actually the shop floor. 00106 */ 00107 else if (!rv && !is_in_shop(victim)) { 00108 opinion = shopkeeper_approval(victim->map, victim); 00109 if (opinion > 0.9) 00110 draw_ext_info(NDI_UNIQUE, 0, victim, MSG_TYPE_SHOP, MSG_TYPE_SHOP_MISC, 00111 "The shopkeeper gives you a friendly wave.", NULL); 00112 else if (opinion > 0.75) 00113 draw_ext_info(NDI_UNIQUE, 0, victim, MSG_TYPE_SHOP, MSG_TYPE_SHOP_MISC, 00114 "The shopkeeper waves to you.", NULL); 00115 else if (opinion > 0.5) 00116 draw_ext_info(NDI_UNIQUE, 0, victim, MSG_TYPE_SHOP, MSG_TYPE_SHOP_MISC, 00117 "The shopkeeper ignores you.", NULL); 00118 else 00119 draw_ext_info(NDI_UNIQUE, 0, victim, MSG_TYPE_SHOP, MSG_TYPE_SHOP_MISC, 00120 "The shopkeeper glares at you with contempt.", NULL); 00121 } 00122 } else { 00123 /* if we get here, a player tried to leave a shop but was not able 00124 * to afford the items he has. We try to move the player so that 00125 * they are not on the mat anymore 00126 */ 00127 int i = find_free_spot(victim, victim->map, victim->x, victim->y, 1, 9); 00128 if (i == -1) 00129 LOG(llevError, "Internal shop-mat problem.\n"); 00130 else { 00131 remove_ob(victim); 00132 victim->x += freearr_x[i]; 00133 victim->y += freearr_y[i]; 00134 rv = insert_ob_in_map(victim, victim->map, trap, 0) == NULL; 00135 esrv_map_scroll(&victim->contr->socket, freearr_x[i], freearr_y[i]); 00136 victim->contr->socket.update_look = 1; 00137 victim->contr->socket.look_position = 0; 00138 } 00139 } 00140 CLEAR_FLAG(victim, FLAG_NO_APPLY); 00141 leave: 00142 common_post_ob_move_on(trap, victim, originator); 00143 return METHOD_OK; 00144 }