ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/shop.C
(Generate patch)

Comparing deliantra/server/server/shop.C (file contents):
Revision 1.76 by root, Fri Mar 26 01:04:45 2010 UTC vs.
Revision 1.80 by root, Wed Apr 28 19:01:01 2010 UTC

90 not_cursed = flag & F_NOT_CURSED; 90 not_cursed = flag & F_NOT_CURSED;
91 approximate = flag & F_APPROX; 91 approximate = flag & F_APPROX;
92 shop = flag & F_SHOP; 92 shop = flag & F_SHOP;
93 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP); 93 flag &= ~(F_NO_BARGAIN | F_IDENTIFIED | F_NOT_CURSED | F_APPROX | F_SHOP);
94 94
95 int number = tmp->number_of ();
96
95 if (tmp->type == MONEY) 97 if (tmp->type == MONEY)
96 return tmp->nrof * tmp->value; 98 return number * tmp->value;
97 99
98 if (tmp->type == GEM) 100 if (tmp->type == GEM)
99 { 101 {
100 if (flag == F_TRUE) 102 if (flag == F_TRUE)
101 return (tmp->nrof * tmp->value); 103 return number * tmp->value;
102 104
103 if (flag == F_BUY) 105 if (flag == F_BUY)
104 return (sint64) (1.03 * tmp->nrof * tmp->value); 106 return 1.03 * number * tmp->value;
105 107
106 if (flag == F_SELL) 108 if (flag == F_SELL)
107 return (sint64) (0.97 * tmp->nrof * tmp->value); 109 return 0.97 * number * tmp->value;
108 110
109 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ()); 111 LOG (llevError, "Query_cost: Gem type with unknown flag %d: %s\n", flag, tmp->debug_desc ());
110 return 0; 112 return 0;
111 } 113 }
112 114
113 int number = tmp->number_of ();
114
115 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified) 115 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
116 { 116 {
117 if (!not_cursed && (QUERY_FLAG (tmp, FLAG_CURSED) || QUERY_FLAG (tmp, FLAG_DAMNED))) 117 if (!not_cursed && (tmp->flag [FLAG_CURSED] || tmp->flag [FLAG_DAMNED]))
118 return 0; 118 return 0;
119 else 119 else
120 val = tmp->value * number; 120 val = number * tmp->value;
121 } 121 }
122 /* This area deals with objects that are not identified, but can be */ 122 /* This area deals with objects that are not identified, but can be */
123 else 123 else
124 { 124 {
125 if (flag == F_BUY) 125 if (flag == F_BUY)
134 else 134 else
135 { 135 {
136 /* Get 2/3'rd value for applied objects, 1/3'rd for totally 136 /* Get 2/3'rd value for applied objects, 1/3'rd for totally
137 * unknown objects 137 * unknown objects
138 */ 138 */
139 if (QUERY_FLAG (tmp, FLAG_BEEN_APPLIED)) 139 if (tmp->flag [FLAG_BEEN_APPLIED])
140 val = number * tmp->arch->value * 2 / 3; 140 val = number * tmp->arch->value * 2 / 3;
141 else 141 else
142 val = number * tmp->arch->value / 3; 142 val = number * tmp->arch->value / 3;
143 } 143 }
144 } 144 }
145 } 145 }
146 146
147 /* If the item has been applied or identifed or does not need to be 147 /* If the item has been applied or identifed or does not need to be
151 * tmp->arch->magic for any magic. The check for archetype 151 * tmp->arch->magic for any magic. The check for archetype
152 * magic is to not give extra money for archetypes that are by 152 * magic is to not give extra money for archetypes that are by
153 * default magical. This is because the archetype value should have 153 * default magical. This is because the archetype value should have
154 * already figured in that value. 154 * already figured in that value.
155 */ 155 */
156 if ((QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified || 156 if ((tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified || tmp->flag [FLAG_BEEN_APPLIED])
157 QUERY_FLAG (tmp, FLAG_BEEN_APPLIED)) && tmp->magic && (tmp->arch == NULL || !tmp->arch->magic)) 157 && tmp->magic && (!tmp->arch || !tmp->arch->magic))
158 { 158 {
159 if (tmp->magic > 0) 159 if (tmp->magic > 0)
160 val *= (3 * tmp->magic * tmp->magic * tmp->magic); 160 val *= 3 * tmp->magic * tmp->magic * tmp->magic;
161 else 161 else
162 /* Note that tmp->magic is negative, so that this 162 /* Note that tmp->magic is negative, so that this
163 * will actually be something like val /=2, /=3, etc. 163 * will actually be something like val /=2, /=3, etc.
164 */ 164 */
165 val /= (1 - tmp->magic); 165 val /= 1 - tmp->magic;
166 } 166 }
167 167
168 if (tmp->type == WAND) 168 if (tmp->type == WAND)
169 { 169 {
170 /* Value of the wand is multiplied by the number of 170 /* Value of the wand is multiplied by the number of
171 * charges. the treasure code already sets up the value 171 * charges. the treasure code already sets up the value
172 * 50 charges is used as the baseline. 172 * 50 charges is used as the baseline.
173 */ 173 */
174 if (QUERY_FLAG (tmp, FLAG_IDENTIFIED) || !need_identify (tmp) || identified) 174 if (tmp->flag [FLAG_IDENTIFIED] || !tmp->need_identify () || identified)
175 val = (val * tmp->stats.food) / 50; 175 val *= tmp->stats.food / 50;
176 else /* if not identified, presume one charge */ 176 else /* if not identified, presume one charge */
177 val /= 50; 177 val /= 50;
178 } 178 }
179 179
180 /* Limit amount of money you can get for really great items. */ 180 /* Limit amount of money you can get for really great items. */
181 if (flag == F_SELL) 181 if (flag == F_SELL)
182 val = value_limit ((sint64) val, number, who, shop); 182 val = value_limit (val, number, who, shop);
183 183
184 // use a nonlinear price adjustment. as my predecessor said, don't change 184 // use a nonlinear price adjustment. as my predecessor said, don't change
185 // the archetypes, its work required for balancing, and we don't care. 185 // the archetypes, its work required for balancing, and we don't care.
186 //val = pow (val, 1.05); 186 //val = pow (val, 1.05);
187 187
218 * will come from the basic stat charisma 218 * will come from the basic stat charisma
219 * the rest will come from the level in bargaining skill 219 * the rest will come from the level in bargaining skill
220 */ 220 */
221 const double cha_ratio = 0.40; 221 const double cha_ratio = 0.40;
222 222
223 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / (double) settings.max_level, 0.25); 223 diff = no_bargain ? 1.0 : 1. - pow (lev_bargain / MAXLEVEL_TREASURE, 0.25);
224 diff = (1. - cha_ratio) * diff + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.); 224 diff = (1. - cha_ratio) * diff + cha_ratio * (cha_bonus[who->stats.Cha] - 1.) / (cha_bonus[who->stats.Cha] + 1.);
225 diff = .02 + (.80 - .02) * diff; 225 diff = .02 + (.80 - .02) * diff;
226 226
227 if (flag == F_BUY) 227 if (flag == F_BUY)
228 val += val * diff; 228 val += val * diff;
230 val -= val * diff; 230 val -= val * diff;
231 231
232 // now find a price range. the less good we can judge, the larger the range is 232 // now find a price range. the less good we can judge, the larger the range is
233 // then the range is adjusted randomly around the correct value 233 // then the range is adjusted randomly around the correct value
234 if (approximate) 234 if (approximate)
235 approx_range = sint64 (val / sqrt (lev_identify * 3 + 1)); 235 approx_range = val / sqrt (lev_identify * 3 + 1);
236 } 236 }
237 237
238 /* I don't think this should really happen - if it does, it indicates and 238 /* I don't think this should really happen - if it does, it indicates and
239 * overflow of diff above. That should only happen if 239 * overflow of diff above. That should only happen if
240 * we are selling objects - in that case, the person just 240 * we are selling objects - in that case, the person just
241 * gets no money. 241 * gets no money.
242 */ 242 */
243 if ((sint64) val < 0) 243 if ((sint64) val < 0)
244 val = 0; 244 val = 0;
245 245
246 /* Unidentified stuff won't sell for more than 60gp */ 246 /* Unidentified stuff won't sell for more than 10gp */
247 if (flag == F_SELL && !QUERY_FLAG (tmp, FLAG_IDENTIFIED) && need_identify (tmp) && !identified) 247 if (flag == F_SELL && !tmp->flag [FLAG_IDENTIFIED] && tmp->need_identify () && !identified)
248 { 248 min_it (val, 1000);
249 val = (val > 600) ? 600 : val;
250 }
251 249
252 /* if we are in a shop, check how the type of shop should affect the price */ 250 /* if we are in a shop, check how the type of shop should affect the price */
253 if (shop && who) 251 if (shop && who)
254 { 252 {
255 if (flag == F_SELL) 253 if (flag == F_SELL)
256 val = (val * shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map)); 254 val *= shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who) / shop_greed (who->map);
257 else if (flag == F_BUY) 255 else if (flag == F_BUY)
258 { 256 {
259 /* 257 /*
260 * when buying, if the item was sold by another player, it is ok to 258 * when buying, if the item was sold by another player, it is ok to
261 * let the item be sold cheaper, according to the specialisation of 259 * let the item be sold cheaper, according to the specialisation of
267 * be sold for (otherwise players could camp map resets to make money). 265 * be sold for (otherwise players could camp map resets to make money).
268 * In game terms, a non-specialist shop, might not recognise the true 266 * In game terms, a non-specialist shop, might not recognise the true
269 * value of the items they sell (much like how people sometimes find 267 * value of the items they sell (much like how people sometimes find
270 * antiques in a junk shop in real life). 268 * antiques in a junk shop in real life).
271 */ 269 */
272 if (QUERY_FLAG (tmp, FLAG_PLAYER_SOLD)) 270 if (tmp->flag [FLAG_PLAYER_SOLD])
273 val = (val * shop_greed (who->map) * shop_specialisation_ratio (tmp, who->map) / shopkeeper_approval (who->map, who)); 271 val *= shop_specialisation_ratio (tmp, who->map);
274 else 272 else
275 val = (val * shop_greed (who->map) / (shop_specialisation_ratio (tmp, who->map) * shopkeeper_approval (who->map, who))); 273 val /= shop_specialisation_ratio (tmp, who->map);
274
275 val *= shop_greed (who->map) / shopkeeper_approval (who->map, who);
276 } 276 }
277 277
278 /* we will also have an extra 0-5% variation between shops of the same type 278 /* we will also have an extra 0-5% variation between shops of the same type
279 * for valuable items (below a value of 50 this effect wouldn't be very 279 * for valuable items (below a value of 50 this effect wouldn't be very
280 * pointful, and could give fun with rounding. 280 * pointful, and could give fun with rounding.
281 */ 281 */
282 //TODO: why use cosf at all, just % and scale linearly, gives more even distribution 282 //TODO: why use cosf at all, just % and scale linearly, gives more even distribution
283 if (val > 50) 283 if (val > 50)
284 val += float (val) * .05f * cosf ((tmp->uuid.seq & 0xffff) * float (M_PI * 2. / 0x10000)); 284 val *= 1 + .05f * cosf ((tmp->uuid.seq & 0xffff) * M_PI * 2. / 0x10000);
285 } 285 }
286 286
287 return (sint64) val; 287 return val;
288} 288}
289 289
290/* Find the coin type that is worth more the 'c'. Starts at the 290/* Find the coin type that is worth more the 'c'. Starts at the
291 * cointype placement. 291 * cointype placement.
292 */ 292 */
296{ 296{
297 archetype *coin; 297 archetype *coin;
298 298
299 do 299 do
300 { 300 {
301 if (coins[*cointype] == NULL) 301 if (!coins [*cointype])
302 return NULL; 302 return 0;
303
303 coin = archetype::find (coins[*cointype]); 304 coin = archetype::find (coins [*cointype]);
305
304 if (coin == NULL) 306 if (!coin)
305 return NULL; 307 return 0;
308
306 *cointype += 1; 309 *cointype += 1;
307 } 310 }
308 while (coin->value > c); 311 while (coin->value > c);
309 312
310 return coin; 313 return coin;
449 } 452 }
450 453
451 for (tmp = op->inv; tmp; tmp = tmp->below) 454 for (tmp = op->inv; tmp; tmp = tmp->below)
452 if (tmp->type == MONEY) 455 if (tmp->type == MONEY)
453 total += tmp->nrof * (sint64)tmp->value; 456 total += tmp->nrof * (sint64)tmp->value;
454 else if (tmp->type == CONTAINER && QUERY_FLAG (tmp, FLAG_APPLIED) && (!tmp->race || tmp->race.contains ("gold"))) 457 else if (tmp->type == CONTAINER && tmp->flag [FLAG_APPLIED] && (!tmp->race || tmp->race.contains ("gold")))
455 total += query_money (tmp); 458 total += query_money (tmp);
456 459
457 return total; 460 return total;
458} 461}
459 462
474 return 0; 477 return 0;
475 478
476 pay_from_container (pl, pl, to_pay); 479 pay_from_container (pl, pl, to_pay);
477 480
478 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 481 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
479 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (!pouch->race || pouch->race.contains ("gold"))) 482 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains ("gold")))
480 pay_from_container (pl, pouch, to_pay); 483 pay_from_container (pl, pouch, to_pay);
481 484
482 pl->update_stats (); 485 pl->update_stats ();
483 return 1; 486 return 1;
484} 487}
511 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE); 514 change_exp (pl, saved_money, "bargaining", SK_EXP_NONE);
512 515
513 pay_from_container (pl, pl, to_pay); 516 pay_from_container (pl, pl, to_pay);
514 517
515 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below) 518 for (pouch = pl->inv; pouch && to_pay; pouch = pouch->below)
516 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && (!pouch->race || pouch->race.contains ("gold"))) 519 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && (!pouch->race || pouch->race.contains ("gold")))
517 pay_from_container (pl, pouch, to_pay); 520 pay_from_container (pl, pouch, to_pay);
518 521
519 pl->update_stats (); 522 pl->update_stats ();
520 523
521 return 1; 524 return 1;
640 LOG (llevError, "can_pay(): called against something that isn't a player\n"); 643 LOG (llevError, "can_pay(): called against something that isn't a player\n");
641 return 0; 644 return 0;
642 } 645 }
643 646
644 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item) 647 for (object::depth_iterator item = pl->begin (); item != pl->end (); ++item)
645 if (QUERY_FLAG (item, FLAG_UNPAID)) 648 if (item->flag [FLAG_UNPAID])
646 { 649 {
647 unpaid_count++; 650 unpaid_count++;
648 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP); 651 unpaid_price += query_cost (item, pl, F_BUY | F_SHOP);
649 } 652 }
650 653
679 { 682 {
680 next_item: 683 next_item:
681 684
682 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op) 685 for (object::depth_iterator op = pl->begin (); op != pl->end (); ++op)
683 { 686 {
684 if (QUERY_FLAG (op, FLAG_UNPAID)) 687 if (op->flag [FLAG_UNPAID])
685 { 688 {
686 char buf[MAX_BUF]; 689 char buf[MAX_BUF];
687 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP)); 690 snprintf (buf, MAX_BUF, "%s", query_cost_string (op, pl, F_BUY | F_SHOP));
688 691
689 if (!pay_for_item (op, pl)) 692 if (!pay_for_item (op, pl))
690 { 693 {
691 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl); 694 sint64 i = query_cost (op, pl, F_BUY | F_SHOP) - query_money (pl);
692 695
693 CLEAR_FLAG (op, FLAG_UNPAID); 696 op->clr_flag (FLAG_UNPAID);
694 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op)); 697 new_draw_info_format (NDI_UNIQUE, 0, pl, "You lack %s to buy %s.", cost_string_from_value (i, 0), query_name (op));
695 SET_FLAG (op, FLAG_UNPAID); 698 op->set_flag (FLAG_UNPAID);
696 return 0; 699 return 0;
697 } 700 }
698 else 701 else
699 { 702 {
700 CLEAR_FLAG (op, FLAG_UNPAID); 703 op->clr_flag (FLAG_UNPAID);
701 CLEAR_FLAG (op, FLAG_PLAYER_SOLD); 704 op->clr_flag (FLAG_PLAYER_SOLD);
702 new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op)); 705 new_draw_info_format (NDI_UNIQUE, 0, op, "You paid %s for %s.", buf, query_name (op));
703 706
704 if (!merge_ob (op, op->env->inv)) 707 if (!merge_ob (op, op->env->inv))
705 esrv_update_item (UPD_FLAGS, pl, op); 708 esrv_update_item (UPD_FLAGS, pl, op);
706 709
739 LOG (llevError, "Could not find %s archetype\n", coins[count]); 742 LOG (llevError, "Could not find %s archetype\n", coins[count]);
740 else if ((amount / at->value) > 0) 743 else if ((amount / at->value) > 0)
741 { 744 {
742 for (pouch = pl->inv; pouch; pouch = pouch->below) 745 for (pouch = pl->inv; pouch; pouch = pouch->below)
743 { 746 {
744 if (pouch->type == CONTAINER && QUERY_FLAG (pouch, FLAG_APPLIED) && pouch->race.contains ("gold")) 747 if (pouch->type == CONTAINER && pouch->flag [FLAG_APPLIED] && pouch->race.contains ("gold"))
745 { 748 {
746 int w = at->weight * (100 - pouch->stats.Str) / 100; 749 int w = at->weight * (100 - pouch->stats.Str) / 100;
747 int n = amount / at->value; 750 int n = amount / at->value;
748 751
749 if (w == 0) 752 if (w == 0)
837 840
838 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.", 841 new_draw_info_format (NDI_UNIQUE, 0, pl, "You receive %s for %s.",
839 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op)); 842 query_cost_string (op, pl, F_SELL | F_SHOP), query_name (op));
840 pl->play_sound (sound_find ("shop_sell")); 843 pl->play_sound (sound_find ("shop_sell"));
841 844
842 SET_FLAG (op, FLAG_UNPAID); 845 op->set_flag (FLAG_UNPAID);
843 identify (op); 846 identify (op);
844 847
845 return true; 848 return true;
846} 849}
847 850
1078 /* clear unpaid flag so that doesn't come up in query 1081 /* clear unpaid flag so that doesn't come up in query
1079 * string. We clear nrof so that we can better sort 1082 * string. We clear nrof so that we can better sort
1080 * the object names. 1083 * the object names.
1081 */ 1084 */
1082 1085
1083 CLEAR_FLAG (tmp, FLAG_UNPAID); 1086 tmp->clr_flag (FLAG_UNPAID);
1084 items[*numitems].nrof = tmp->nrof; 1087 items[*numitems].nrof = tmp->nrof;
1085 /* Non mergable items have nrof of 0, but count them as one 1088 /* Non mergable items have nrof of 0, but count them as one
1086 * so the display is properly. 1089 * so the display is properly.
1087 */ 1090 */
1088 if (tmp->nrof == 0) 1091 if (tmp->nrof == 0)
1111 items[*numitems].item_real = strdup (query_base_name (tmp, 1)); 1114 items[*numitems].item_real = strdup (query_base_name (tmp, 1));
1112 (*numitems)++; 1115 (*numitems)++;
1113 break; 1116 break;
1114 } 1117 }
1115 1118
1116 SET_FLAG (tmp, FLAG_UNPAID); 1119 tmp->set_flag (FLAG_UNPAID);
1117} 1120}
1118 1121
1119void 1122void
1120shop_listing (object *sign, object *op) 1123shop_listing (object *sign, object *op)
1121{ 1124{
1143 items = (shopinv *)malloc (sizeof (shopinv) * numallocated); 1146 items = (shopinv *)malloc (sizeof (shopinv) * numallocated);
1144 1147
1145 /* Find all the appropriate items */ 1148 /* Find all the appropriate items */
1146 for (i = x1; i <= x2; i++) 1149 for (i = x1; i <= x2; i++)
1147 for (j = y1; j < y2; j++) 1150 for (j = y1; j < y2; j++)
1148 if (is_in_shop (op->map, i, j)) 1151 if (op->map->is_in_shop (i, j))
1149 { 1152 {
1150 stack = GET_MAP_OB (op->map, i, j); 1153 stack = GET_MAP_OB (op->map, i, j);
1151 1154
1152 while (stack) 1155 while (stack)
1153 { 1156 {
1154 if (QUERY_FLAG (stack, FLAG_UNPAID)) 1157 if (stack->flag [FLAG_UNPAID])
1155 { 1158 {
1156 if (numitems == numallocated) 1159 if (numitems == numallocated)
1157 items = (shopinv *)realloc (items, sizeof (shopinv) * (numallocated *= 2)); 1160 items = (shopinv *)realloc (items, sizeof (shopinv) * (numallocated *= 2));
1158 1161
1159 add_shop_item (stack, items, &numitems, &numallocated); 1162 add_shop_item (stack, items, &numitems, &numallocated);
1183 op->contr->infobox (MSG_CHANNEL ("shopitems"), buf); 1186 op->contr->infobox (MSG_CHANNEL ("shopitems"), buf);
1184 1187
1185 free (items); 1188 free (items);
1186} 1189}
1187 1190
1188/* elmex: this function checks whether the object is in a shop */
1189bool
1190is_in_shop (object *o)
1191{
1192 if (!o->is_on_map ())
1193 return false;
1194
1195 return is_in_shop (o->map, o->x, o->y);
1196}
1197
1198/* elmex: this function checks whether we are in a shop or not 1191/* elmex: this function checks whether we are in a shop or not
1199 - change 2007-11-26: enhanced the O(n) case by stopping at the first 1192 - change 2007-11-26: enhanced the O(n) case by stopping at the first
1200 floor tile. this possibly will make map bugs where shopfloors are above 1193 floor tile. this possibly will make map bugs where shopfloors are above
1201 floors more obvious. 1194 floors more obvious.
1202*/ 1195*/
1203
1204bool 1196bool
1205is_in_shop (maptile *map, int x, int y) 1197maptile::is_in_shop (int x, int y) const
1206{ 1198{
1207 for (object *floor = GET_MAP_OB (map, x, y); floor; floor = floor->above) 1199 for (object *floor = at (x, y).bot; floor; floor = floor->above)
1208 if (QUERY_FLAG (floor, FLAG_IS_FLOOR)) 1200 if (floor->flag [FLAG_IS_FLOOR])
1209 return floor->type == SHOP_FLOOR; 1201 return floor->type == SHOP_FLOOR;
1210 1202
1211 return false; 1203 return false;
1212} 1204}
1213 1205

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines