void do_sell( CHAR_DATA *ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; CHAR_DATA *keeper; OBJ_DATA *obj; int cost; one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Sell what?\n\r", ch ); return; } if ( ( keeper = find_keeper( ch ) ) == NULL ) return; if ( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { act( AT_TELL, "$n tells you 'You don't have that item.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } /* Bug report and solution thanks to [email protected] */ if ( !can_see_obj( keeper, obj) ) { send_to_char("What are you trying to sell me? I don't buy thin air!\n\r", ch ); return; } if ( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it!\n\r", ch ); return; } if ( obj->timer > 0 ) { act( AT_TELL, "$n tells you, '$p is depreciating in value too quickly...'", keeper, obj, ch, TO_VICT ); return; } if ( ( cost = get_cost( ch, keeper, obj, FALSE ) ) <= 0 ) { act( AT_ACTION, "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT ); return; } if ( cost > keeper->gold ) { act( AT_TELL, "$n makes a credit transaction.", keeper, obj, ch, TO_VICT ); lower_economy( ch->in_room->area, cost-keeper->gold ); } separate_obj( obj ); act( AT_ACTION, "$n sells $p.", ch, obj, NULL, TO_ROOM ); sprintf( buf, "You sell $p for %d credit%s.", cost, cost == 1 ? "" : "s" ); act( AT_ACTION, buf, ch, obj, NULL, TO_CHAR ); ch->gold += cost; keeper->gold -= cost; if ( keeper->gold < 0 ) keeper->gold = 0; if ( obj->item_type == ITEM_TRASH ) extract_obj( obj ); else if ( IS_SET( obj->extra_flags , ITEM_CONTRABAND) ) { long ch_exp; ch_exp = UMIN( obj->cost*10 , ( exp_level( ch->skill_level[SMUGGLING_ABILITY]+1) - exp_level( ch->skill_level[SMUGGLING_ABILITY]) ) / 10 ); ch_printf( ch, "You receive %ld smuggling experience for unloading your contraband.\n\r " , ch_exp ); gain_exp( ch, ch_exp , SMUGGLING_ABILITY ); if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE ) extract_obj( obj ); else { REMOVE_BIT( obj->extra_flags , ITEM_CONTRABAND ); obj_from_char( obj ); obj_to_char( obj, keeper ); } } else if ( obj->item_type == ITEM_SPICE || obj->item_type == ITEM_RAWSPICE ) extract_obj( obj ); else { obj_from_char( obj ); obj_to_char( obj, keeper ); } return; }
void do_buy( CHAR_DATA *ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; int maxgold; bool debit; OBJ_DATA *obj; argument = one_argument( argument, arg ); if ( arg[0] == '\0' ) { send_to_char( "Buy what?\n\r", ch ); return; } if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) ) { char buf[MAX_STRING_LENGTH]; CHAR_DATA *pet; ROOM_INDEX_DATA *pRoomIndexNext; ROOM_INDEX_DATA *in_room; if ( argument[0] == '\0' ) debit = FALSE; else if ( !str_cmp( "atm", argument ) || !str_cmp( "debit", argument ) ) { bool has_card = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if ( obj->item_type == ITEM_DEBIT_CARD ) has_card = TRUE; } if ( has_card == TRUE ) debit = TRUE; else { send_to_char( "You don't even have your card with you!\n\r", ch ); return; } } if ( IS_NPC(ch) ) return; pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 ); if ( !pRoomIndexNext ) { bug( "Do_buy: bad pet shop at vnum %d.", ch->in_room->vnum ); send_to_char( "Sorry, you can't buy that here.\n\r", ch ); return; } in_room = ch->in_room; ch->in_room = pRoomIndexNext; pet = get_char_room( ch, arg ); ch->in_room = in_room; if ( pet == NULL || !IS_NPC( pet ) || !IS_SET(pet->act, ACT_PET) ) { send_to_char( "Sorry, you can't buy that here.\n\r", ch ); return; } if (( ch->gold < 10 * pet->top_level * pet->top_level ) && debit == FALSE) { send_to_char( "You can't afford it.\n\r", ch ); return; } else if ( (ch->pcdata->bank < 10 * pet->top_level * pet->top_level) && debit == TRUE ) { send_to_char( "You dont have enough money in your bank account for it.\n\r", ch ); return; } maxgold = 10 * pet->top_level * pet->top_level; if ( debit == FALSE ) ch->gold -= maxgold; /* this was already here, btw */ else ch->pcdata->bank -= maxgold; boost_economy( ch->in_room->area, maxgold ); pet = create_mobile( pet->pIndexData ); SET_BIT(pet->act, ACT_PET); SET_BIT(pet->affected_by, AFF_CHARM); argument = one_argument( argument, arg ); if ( arg[0] != '\0' ) { sprintf( buf, "%s %s", pet->name, arg ); STRFREE( pet->name ); pet->name = STRALLOC( buf ); } sprintf( buf, "%sA neck tag says 'I belong to %s'.\n\r", pet->description, ch->name ); STRFREE( pet->description ); pet->description = STRALLOC( buf ); char_to_room( pet, ch->in_room ); add_follower( pet, ch ); send_to_char( "Enjoy your pet.\n\r", ch ); act( AT_ACTION, "$n bought $N as a pet.", ch, NULL, pet, TO_ROOM ); return; } else { CHAR_DATA *keeper; int cost; int noi = 1; /* Number of items */ sh_int mnoi = 20; /* Max number of items to be bought at once */ if ( ( keeper = find_keeper( ch ) ) == NULL ) return; maxgold = keeper->top_level * 10; if ( is_number( arg ) ) { noi = atoi( arg ); argument = one_argument( argument, arg ); if ( noi > mnoi ) { act( AT_TELL, "$n tells you 'I don't sell that many items at" " once.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } } if ( argument[0] == '\0' ) debit = FALSE; else if ( !str_cmp( "atm", argument ) || !str_cmp( "debit", argument ) ) { bool has_card = FALSE; for ( obj = ch->last_carrying; obj; obj = obj->prev_content ) { if ( obj->item_type == ITEM_DEBIT_CARD ) has_card = TRUE; } if ( has_card == TRUE ) debit = TRUE; else { send_to_char( "You don't even have your card with you!\n\r", ch ); return; } } obj = get_obj_carry( keeper, arg ); if ( !obj && arg[0] == '#' ) { int onum, oref; bool ofound = FALSE; onum =0; oref = atoi(arg+1); for ( obj = keeper->last_carrying; obj; obj = obj->prev_content ) { if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) ) onum++; if ( onum == oref ) { ofound = TRUE; break; } else if ( onum > oref ) break; } if (!ofound) obj = NULL; } if (keeper->home != NULL && obj->cost > 0) cost= obj->cost; cost = ( get_cost( ch, keeper, obj, TRUE ) * noi ); if( !IS_NPC(ch) && ch->pcdata->learned[gsn_bargain] > 0 && ch->pcdata->learned[gsn_bargain] > number_percent()) { ch_printf(ch,"You are able to bargain from %d credits to %d credits!\n\r", cost, (cost/3)+(cost/2)); cost = (cost/3) + (cost/2); if(number_percent() > 50) learn_from_success(ch, gsn_bargain); } if ( cost <= 0 || !can_see_obj( ch, obj ) ) { act( AT_TELL, "$n tells you 'I don't sell that -- try 'list'.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) && ( noi > 1 ) ) { interpret( keeper, "laugh" ); act( AT_TELL, "$n tells you 'I don't have enough of those in stock" " to sell more than one at a time.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if ( ch->gold < cost && debit == FALSE) { act( AT_TELL, "$n tells you 'You can't afford to buy $p.'", keeper, obj, ch, TO_VICT ); ch->reply = keeper; return; } if ( ch->pcdata->bank < cost && debit == TRUE) { send_to_char( "You are almost slide your card through, but you remember you don't have enough money!\n\r", ch ); return; } if ( IS_SET(obj->extra_flags, ITEM_PROTOTYPE) && get_trust( ch ) < LEVEL_IMMORTAL ) { act( AT_TELL, "$n tells you 'This is a only a prototype! I can't sell you that...'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if ( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) ) { send_to_char( "You can't carry that many items.\n\r", ch ); return; } if ( ch->carry_weight + ( get_obj_weight( obj ) * noi ) + (noi > 1 ? 2 : 0) > can_carry_w( ch ) ) { send_to_char( "You can't carry that much weight.\n\r", ch ); return; } if ( noi == 1 ) { if ( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) separate_obj( obj ); act( AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You buy $p.", ch, obj, NULL, TO_CHAR ); } else { sprintf( arg, "$n buys %d $p%s.", noi, ( obj->short_descr[strlen(obj->short_descr)-1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_ROOM ); sprintf( arg, "You buy %d $p%s.", noi, ( obj->short_descr[strlen(obj->short_descr)-1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_CHAR ); act( AT_ACTION, "$N puts them into a bag and hands it to you.", ch, NULL, keeper, TO_CHAR ); } if ( debit == FALSE ) ch->gold -= cost; /* this line was already here, btw */ else if ( debit == TRUE ) ch->pcdata->bank -= cost; keeper->gold += cost; if ( keeper->gold > maxgold ) { boost_economy( keeper->in_room->area, keeper->gold - maxgold/2 ); keeper->gold = maxgold/2; act( AT_ACTION, "$n puts some credits into a large safe.", keeper, NULL, NULL, TO_ROOM ); } if ( IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) { OBJ_DATA *buy_obj, *bag; buy_obj = create_object( obj->pIndexData, obj->level ); /* * Due to grouped objects and carry limitations in SMAUG * The shopkeeper gives you a bag with multiple-buy, * and also, only one object needs be created with a count * set to the number bought. -Thoric */ if ( noi > 1 ) { bag = create_object( get_obj_index( OBJ_VNUM_SHOPPING_BAG ), 1 ); /* perfect size bag ;) */ bag->value[0] = bag->weight + (buy_obj->weight * noi); buy_obj->count = noi; obj->pIndexData->count += (noi - 1); numobjsloaded += (noi - 1); obj_to_obj( buy_obj, bag ); obj_to_char( bag, ch ); } else obj_to_char( buy_obj, ch ); } else { obj_from_char( obj ); obj_to_char( obj, ch ); } return; } }
void do_list( CHAR_DATA *ch, char *argument ) { if ( IS_SET(ch->in_room->room_flags, ROOM_PET_SHOP) ) { ROOM_INDEX_DATA *pRoomIndexNext; CHAR_DATA *pet; bool found; pRoomIndexNext = get_room_index( ch->in_room->vnum + 1 ); if ( !pRoomIndexNext ) { bug( "Do_list: bad pet shop at vnum %d.", ch->in_room->vnum ); send_to_char( "You can't do that here.\n\r", ch ); return; } found = FALSE; for ( pet = pRoomIndexNext->first_person; pet; pet = pet->next_in_room ) { if ( IS_SET(pet->act, ACT_PET) && IS_NPC(pet) ) { if ( !found ) { found = TRUE; send_to_char( "Pets for sale:\n\r", ch ); } ch_printf( ch, "[%2d] %8d - %s\n\r", pet->top_level, 10 * pet->top_level * pet->top_level, pet->short_descr ); } } if ( !found ) send_to_char( "Sorry, we're out of pets right now.\n\r", ch ); return; } else { char arg[MAX_INPUT_LENGTH]; CHAR_DATA *keeper; OBJ_DATA *obj; int cost; int oref = 0; bool found; one_argument( argument, arg ); if ( ( keeper = find_keeper( ch ) ) == NULL ) return; found = FALSE; for ( obj = keeper->last_carrying; obj; obj = obj->prev_content ) { if ( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) ) { oref++; if ( ( cost = get_cost( ch, keeper, obj, TRUE ) ) > 0 && ( arg[0] == '\0' || nifty_is_name( arg, obj->name ) ) ) { if (keeper->home != NULL) cost = obj->cost; if ( !found ) { found = TRUE; ch_printf( ch, "%s[Price] {ref} Item\n\r", color_str( AT_LIST, ch) ); } ch_printf( ch, "%s[%5d] {%3d} %s%s%s.\n\r", color_str(AT_LIST, ch), cost, oref, capitalize( obj->short_descr ), color_str(AT_LIST, ch), IS_SET(obj->extra_flags, ITEM_HUTT_SIZE) ? " (hutt size)" : ( IS_SET(obj->extra_flags, ITEM_LARGE_SIZE) ? " (large)" : ( IS_SET(obj->extra_flags, ITEM_HUMAN_SIZE) ? " (medium)" : ( IS_SET(obj->extra_flags, ITEM_SMALL_SIZE) ? " (small)" : "" ) ) ) ); } } } if ( !found ) { if ( arg[0] == '\0' ) send_to_char( "You can't buy anything here.\n\r", ch ); else send_to_char( "You can't buy that here.\n\r", ch ); } return; } }
void solve_bipartite_matching() { for(size_t max_match=0; max_match<nel; ++max_match) { size_t x, y, root=MINUS_ONE; //just counters and root vertex std::vector<size_t> q(nel); size_t wr = 0, rd = 0; //q - queue for bfs, wr,rd - write and read //pos in queue S.assign(nel, false); //init set S T.assign(nel, false); //init set T prev.assign(nel, MINUS_ONE); //init set prev - for the alternating tree for (x = 0; x < nel; x++) //finding root of the tree if (xy[x] == MINUS_ONE) { q[wr++] = root = x; prev[x] = MINUS_TWO; S[x] = true; break; } for (y = 0; y < nel; y++) //initializing slack array { //std::cerr << "root " << root << " y " << y << std::endl; slack[y] = lx[root] + ly[y] - get_cost(root,y); slackx[y] = root; } //second part of augment() function bool found= false; while (!found) //main cycle { while (rd < wr && !found) //building tree with bfs cycle { x = q[rd++]; //current vertex from X part for (y = 0; y < nel && !found;) //iterate through all edges in equality graph { if (get_cost(x,y) == lx[x] + ly[y] && !T[y]) { if (yx[y] == MINUS_ONE) { found= true; //an exposed vertex in Y found, so } //augmenting path exists! else { T[y] = true; //else just add y to T, q[wr++] = yx[y]; //add vertex yx[y], which is matched //with y, to the queue add_to_tree(yx[y], x); //add edges (x,y) and (y,yx[y]) to the tree ++y; } } else ++y; } } if (!found) { update_labels(); //augmenting path not found, so improve labeling wr = rd = 0; for (y = 0; y < nel && !found;) { //in this cycle we add edges that were added to the equality graph as a //result of improving the labeling, we add edge (slackx[y], y) to the tree if //and only if !T[y] && slack[y] == 0, also with this edge we add another one //(y, yx[y]) or augment the matching, if y was exposed if (!T[y] && slack[y] == 0) { if (yx[y] == MINUS_ONE) //exposed vertex in Y found - augmenting path exists! { x = slackx[y]; found = true; } else { T[y] = true; //else just add y to T, if (!S[yx[y]]) { q[wr++] = yx[y]; //add vertex yx[y], which is matched with //y, to the queue add_to_tree(yx[y], slackx[y]); //and add edges (x,y) and (y, //yx[y]) to the tree } ++y; } } else ++y; } } } assert(found); //in this cycle we inverse edges along augmenting path for (size_t cx = x, cy = y, ty; cx != MINUS_TWO; cx = prev[cx], cy = ty) { ty = xy[cx]; yx[cy] = cx; xy[cx] = cy; } } }
static void add_neighbours_to_queue(carmen_roadmap_t *roadmap, int id, int goal_id, double *fwd_utilities, double *open_list, queue state_queue) { int i; double new_util; double parent_utility; double cost, heuristic; carmen_roadmap_vertex_t *node_list; carmen_roadmap_edge_t *edges; int neighbour_id; double best_known_answer; int best_known_edge; node_list = (carmen_roadmap_vertex_t *)(roadmap->nodes->list); parent_utility = fwd_utilities[id]; assert (parent_utility < 1e5); if (node_list[id].edges->length == 0) construct_edges(roadmap, id); edges = (carmen_roadmap_edge_t *)node_list[id].edges->list; assert(node_list[id].edges->length > 0); best_known_answer = FLT_MAX; best_known_edge = -1; for (i = 0; i < node_list[id].edges->length; i++) { neighbour_id = edges[i].id; if (node_list[neighbour_id].utility > FLT_MAX/2) continue; cost = get_cost(node_list+neighbour_id, node_list+id, roadmap); new_util = parent_utility+cost+node_list[neighbour_id].utility; if (best_known_answer > new_util) { best_known_answer = new_util; best_known_edge = i; } } for (i = 0; i < node_list[id].edges->length; i++) { neighbour_id = edges[i].id; if (open_list[neighbour_id] == -2) continue; cost = get_cost(node_list+neighbour_id, node_list+id, roadmap); if (node_list[neighbour_id].utility < FLT_MAX/2) { if (i != best_known_edge) continue; new_util = parent_utility+cost+node_list[neighbour_id].utility; } else { heuristic = hypot(node_list[goal_id].x - node_list[neighbour_id].x, node_list[goal_id].y - node_list[neighbour_id].y); new_util = parent_utility + cost + heuristic; } if (0 && id == 576) carmen_warn("considering %d : %f : %f %f %f : %f \n", neighbour_id, cost, fwd_utilities[neighbour_id], parent_utility, cost, node_list[id].utility); if (cost > 1e5) continue; assert(new_util < 1e5); if (open_list[neighbour_id] >= 0) { // assert (open_list[neighbour_id] <= new_util); if (open_list[neighbour_id] > new_util) { // carmen_warn("Lowering cost\n"); lower_cost(neighbour_id, id, cost, new_util, state_queue); open_list[neighbour_id] = new_util; } continue; } open_list[neighbour_id] = new_util; if (0) carmen_warn("pushed %d parent %d : %f %f %f\n", neighbour_id, id, cost, fwd_utilities[id], parent_utility+cost); push_state(neighbour_id, id, cost, new_util, state_queue); } /* End of for (i = 0...) */ }
// Take one step forward in the search and return the resulting state int AStar::search_step(void) { // Break if the search is not initialised or the search is finished if(search_state != SEARCH_STATE_SEARCHING) return search_state; // If the open list is empty, there is no solution, // set state to failed and return if(open.empty()) return search_state = SEARCH_STATE_FAILED; steps++; // Get the best node from the open list (pop the heap) Node* n = open.front(); std::pop_heap(open.begin(), open.end(), NodeCmp()); open.pop_back(); // Check if this was the goal, if it was we're done if(n == goal) { // If the goal and start is not the same node, // reconstruct the solution path if(n != start) { // Set the child pointers in each node // (except goal which has no child) Node* child_node = goal; Node* parent_node = goal->parent; do { // set pointer parent_node->child = child_node; // move on to next child_node = parent_node; parent_node = parent_node->parent; } while(child_node != start); // start is always the first node } return search_state = SEARCH_STATE_SUCCEEDED; } else { // if not the goal // We now need to get the successors (neigbours) of this node, // the neighbours are placed in the list successors get_successors(n); // Handle each successor for(NodeListIterator succ = successors.begin(); succ != successors.end(); succ++) { // Calculate the cost from start to this node float newg = n->g + get_cost(n,(*succ)); // Now we need to find whether the node is already on the open or // closed lists. If it is but the node that is already on them is // better (lower g) then we can forget about this successor // First linear search of open list to find node // TODO: Improve to better complexity than linear NodeListIterator open_it; for(open_it = open.begin(); open_it != open.end(); open_it++){ if((*open_it) == (*succ)) break; } if((open_it != open.end()) && ((*open_it)->g <= newg)) continue; // Now do the same check on closed list NodeListIterator closed_it; for(closed_it = closed.begin(); closed_it != closed.end(); closed_it++){ if((*closed_it) == (*succ)) break; } if((closed_it != closed.end()) && ((*closed_it)->g <= newg)) continue; // This node is the best node so far so // lets keep it and set up its A* data (*succ)->parent = n; (*succ)->g = newg; (*succ)->h = estimate_cost_to_goal((*succ)); (*succ)->f = (*succ)->g + (*succ)->h; (*succ)->visited = true; // Remove successor from closed if it was on it if(closed_it != closed.end()) closed.erase(closed_it); // If not in open yet, push node onto open // else make sure to keep the heap structure if(open_it == open.end()){ open.push_back((*succ)); std::push_heap(open.begin(), open.end(), NodeCmp()); } else { std::make_heap(open.begin(), open.end(), NodeCmp()); } } // Push n onto closed, as we have expanded it now closed.push_back(n); } return search_state; // return the resulting state of this search step }
int main () { long i, j, k; long l, r, u, d; long now; Node start, g; long count; long step; char buf[32]; long x; long pre_x; long dif; long max = 0; scanf ("%ld %ld %ld", &H, &W, &T); for (i = 1; i <= H; i++) { scanf ("%s", buf); for (j = 1; j <= W; j++) { s[i][j] = buf[j - 1]; if (s[i][j] == 'S') { start.h = i; start.w = j; start.n = (i - 1) * W + j; } if (s[i][j] == 'G') { g.h = i; g.w = j; g.n = (i - 1) * W + j; } } } x = T / 2; dif = T / 2; while (1) { init (); for (i = 1; i <= H; i++) { for (j = 1; j <= W; j++) { now = (i - 1) * W + j; l = now - 1; r = now + 1; u = now - W; d = now + W; if (j > 1) { dis[l][now] = get_cost (s[i][j], x); } if (j < W) { dis[r][now] = get_cost (s[i][j], x); } if (i > 1) { dis[u][now] = get_cost (s[i][j], x); } if (i < H) { dis[d][now] = get_cost (s[i][j], x); } } } for (k = 1; k <= H * W; k++) for (i = 1; i <= H * W; i++) for (j = 1; j <= H * W; j++) dis[i][j] = min (dis[i][j], dis[i][k] + dis[k][j]); if (dis[start.n][g.n] <= T) { if (max < x) max = x; x += (dif / 2); } else { x -= (dif / 2); } if (dif <= 0) break; dif /= 2; } x = max + 1; while (1) { init (); for (i = 1; i <= H; i++) { for (j = 1; j <= W; j++) { now = (i - 1) * W + j; l = now - 1; r = now + 1; u = now - W; d = now + W; if (j > 1) { dis[l][now] = get_cost (s[i][j], x); } if (j < W) { dis[r][now] = get_cost (s[i][j], x); } if (i > 1) { dis[u][now] = get_cost (s[i][j], x); } if (i < H) { dis[d][now] = get_cost (s[i][j], x); } } } for (k = 1; k <= H * W; k++) for (i = 1; i <= H * W; i++) for (j = 1; j <= H * W; j++) dis[i][j] = min (dis[i][j], dis[i][k] + dis[k][j]); if (dis[start.n][g.n] <= T) { if (max < x) max = x; x++; } else { break; } } printf ("%ld\n", max); return 0; }
int Generic_map::get_cost(Tripoint p) { return get_cost(p.x, p.y, p.z); }
bool Generic_map::blocked(int x, int y, int z) { return (get_cost(x, y, z) <= 0); }
int Generic_map::get_cost(Point p) { return get_cost(p.x, p.y, 0); }
void do_sell( CHAR_DATA * ch, char *argument ) { char buf[MAX_STRING_LENGTH]; char arg[MAX_INPUT_LENGTH]; CHAR_DATA *keeper = NULL; OBJ_DATA *obj = NULL; int cost = 0; one_argument( argument, arg ); if( arg[0] == '\0' ) { send_to_char( "Sell what?\r\n", ch ); return; } if( ( keeper = find_keeper( ch ) ) == NULL ) return; if( ( obj = get_obj_carry( ch, arg ) ) == NULL ) { act( AT_TELL, "$n tells you 'You don't have that item.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if( !can_drop_obj( ch, obj ) ) { send_to_char( "You can't let go of it!\r\n", ch ); return; } if( obj->timer > 0 ) { act( AT_TELL, "$n tells you, '$p is depreciating in value too quickly...'", keeper, obj, ch, TO_VICT ); return; } if( ( cost = get_cost( ch, keeper, obj, FALSE ) ) <= 0 ) { act( AT_ACTION, "$n looks uninterested in $p.", keeper, obj, ch, TO_VICT ); return; } if( cost > keeper->gold ) { act( AT_TELL, "$n makes a credit transaction.", keeper, obj, ch, TO_VICT ); } separate_obj( obj ); act( AT_ACTION, "$n sells $p.", ch, obj, NULL, TO_ROOM ); sprintf( buf, "You sell $p for %d credit%s.", cost, cost == 1 ? "" : "s" ); act( AT_ACTION, buf, ch, obj, NULL, TO_CHAR ); ch->gold += cost; keeper->gold -= cost; if( keeper->gold < 0 ) keeper->gold = 0; if( obj->item_type == ITEM_TRASH ) extract_obj( obj ); else { obj_from_char( obj ); obj_to_char( obj, keeper ); } return; }
void do_buy( CHAR_DATA * ch, char *argument ) { char arg[MAX_INPUT_LENGTH]; int maxgold = 0; argument = one_argument( argument, arg ); if( arg[0] == '\0' ) { send_to_char( "Buy what?\r\n", ch ); return; } /* in case of different shop types */ { CHAR_DATA *keeper = NULL; OBJ_DATA *obj = NULL; int cost = 0; int noi = 1; /* Number of items */ short mnoi = 20; /* Max number of items to be bought at once */ if( ( keeper = find_keeper( ch ) ) == NULL ) return; maxgold = keeper->top_level * 10; if( is_number( arg ) ) { noi = atoi( arg ); argument = one_argument( argument, arg ); if( noi > mnoi ) { act( AT_TELL, "$n tells you 'I don't sell that many items at" " once.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } } obj = get_obj_carry( keeper, arg ); if( !obj && arg[0] == '#' ) { int onum = 0, oref = atoi( arg + 1 ); bool ofound = FALSE; for( obj = keeper->last_carrying; obj; obj = obj->prev_content ) { if( obj->wear_loc == WEAR_NONE && can_see_obj( ch, obj ) ) onum++; if( onum == oref ) { ofound = TRUE; break; } else if( onum > oref ) break; } if( !ofound ) obj = NULL; } cost = ( get_cost( ch, keeper, obj, TRUE ) * noi ); if( cost <= 0 || !can_see_obj( ch, obj ) ) { act( AT_TELL, "$n tells you 'I don't sell that -- try 'list'.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) && ( noi > 1 ) ) { char buf[MAX_STRING_LENGTH]; snprintf( buf, MAX_STRING_LENGTH, "%s", "laugh" ); interpret( keeper, buf ); act( AT_TELL, "$n tells you 'I don't have enough of those in stock" " to sell more than one at a time.'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if( ch->gold < cost ) { act( AT_TELL, "$n tells you 'You can't afford to buy $p.'", keeper, obj, ch, TO_VICT ); ch->reply = keeper; return; } if( IS_SET( obj->extra_flags, ITEM_PROTOTYPE ) && IS_IMMORTAL( ch ) ) { act( AT_TELL, "$n tells you 'This is a only a prototype! I can't sell you that...'", keeper, NULL, ch, TO_VICT ); ch->reply = keeper; return; } if( ch->carry_number + get_obj_number( obj ) > can_carry_n( ch ) ) { send_to_char( "You can't carry that many items.\r\n", ch ); return; } if( ch->carry_weight + ( get_obj_weight( obj ) * noi ) + ( noi > 1 ? 2 : 0 ) > can_carry_w( ch ) ) { send_to_char( "You can't carry that much weight.\r\n", ch ); return; } if( noi == 1 ) { if( !IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) separate_obj( obj ); act( AT_ACTION, "$n buys $p.", ch, obj, NULL, TO_ROOM ); act( AT_ACTION, "You buy $p.", ch, obj, NULL, TO_CHAR ); } else { sprintf( arg, "$n buys %d $p%s.", noi, ( obj->short_descr[strlen( obj->short_descr ) - 1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_ROOM ); sprintf( arg, "You buy %d $p%s.", noi, ( obj->short_descr[strlen( obj->short_descr ) - 1] == 's' ? "" : "s" ) ); act( AT_ACTION, arg, ch, obj, NULL, TO_CHAR ); act( AT_ACTION, "$N puts them into a bag and hands it to you.", ch, NULL, keeper, TO_CHAR ); } ch->gold -= cost; keeper->gold += cost; if( keeper->gold > maxgold ) { keeper->gold = maxgold / 2; act( AT_ACTION, "$n puts some credits into a large safe.", keeper, NULL, NULL, TO_ROOM ); } if( IS_OBJ_STAT( obj, ITEM_INVENTORY ) ) { OBJ_DATA *buy_obj = create_object( obj->pIndexData ); OBJ_DATA *bag = NULL; /* * Due to grouped objects and carry limitations in SMAUG * The shopkeeper gives you a bag with multiple-buy, * and also, only one object needs be created with a count * set to the number bought. -Thoric */ if( noi > 1 ) { bag = create_object( get_obj_index( OBJ_VNUM_SHOPPING_BAG ) ); /* perfect size bag ;) */ bag->value[0] = bag->weight + ( buy_obj->weight * noi ); buy_obj->count = noi; obj->pIndexData->count += ( noi - 1 ); numobjsloaded += ( noi - 1 ); obj_to_obj( buy_obj, bag ); obj_to_char( bag, ch ); } else obj_to_char( buy_obj, ch ); } else { obj_from_char( obj ); obj_to_char( obj, ch ); } return; } }
bool placement_problem::operator<(placement_problem const & o) const{ if(is_feasible() and o.is_feasible()) return get_cost() < o.get_cost(); else return (not is_feasible()) and o.is_feasible(); // Unfeasible first }
void player_move(int direction) { int dx = 0; int dy = 0; switch(direction) { case DIRECTION_NORTH: dy = -1; break; case DIRECTION_SOUTH: dy = 1; break; case DIRECTION_EAST: dx = 1; break; case DIRECTION_WEST: dx = -1; break; case DIRECTION_NORTHEAST: dx = 1; dy = -1; break; case DIRECTION_NORTHWEST: dx = -1; dy = -1; break; case DIRECTION_SOUTHEAST: dx = 1; dy = 1; break; case DIRECTION_SOUTHWEST: dx = -1; dy = 1; break; case DIRECTION_UP: if(z > 0 && is_up_stairs(x, y, current_map)) z--; return; case DIRECTION_DOWN: if(z < LEVEL_COUNT - 1 && is_down_stairs(x, y, current_map)) z++; return; } int res = can_move(x + dx, y + dy, current_map); if(res == 1) { x += dx; y += dy; int cost = 1 + get_cost(x, y, current_map); if(dx != 0 && dy != 0) cost *= 1.5; ep_current -= cost; if(ep_current <= 0) add_message(COLOR_EP_CRIT, "Out of energy, you fall to the ground."); else describe_ground(x, y, current_map); } else if(res == 2) { actor* act = get_actor_at(x + dx, y + dy, current_map); int astr = str; for(int i = 0; i < SLOT_COUNT; ++i) if(equipment[i]) astr += equipment[i]->str; int dmg = damage_actor(act, astr); char* damage_text = 0; if(dmg > 0) { int len = snprintf(0, 0, "You hit the %s for %d damage", act->name, dmg); damage_text = calloc(len + 1, sizeof(char)); snprintf(damage_text, len + 1, "You hit the %s for %d damage", act->name, dmg); } else { int len = snprintf(0, 0, "You miss the %s", act->name); damage_text = calloc(len + 1, sizeof(char)); snprintf(damage_text, len + 1, "You miss the %s", act->name); } if(act->hp <= 0) { printf_message(COLOR_DEFAULT, "You kill the %s!", act->name); add_xp(act->xp); } else add_message(COLOR_DEFAULT, damage_text); free(damage_text); } }