Exemple #1
0
// юзается исключительно в act.wizards.cpp в имм командах "advance" и "set exp".
void gain_exp_regardless(CHAR_DATA * ch, int gain)
{
	int is_altered = FALSE;
	int num_levels = 0;

	ch->set_exp(ch->get_exp() + gain);
	if (!IS_NPC(ch))
	{
		if (gain > 0)
		{
			while (GET_LEVEL(ch) < LVL_IMPL && GET_EXP(ch) >= level_exp(ch, GET_LEVEL(ch) + 1))
			{
				ch->set_level(ch->get_level() + 1);
				num_levels++;
				sprintf(buf, "%sВы достигли следующего уровня!%s\r\n",
						CCWHT(ch, C_NRM), CCNRM(ch, C_NRM));
				send_to_char(buf, ch);

				advance_level(ch);
				is_altered = TRUE;
			}

			if (is_altered)
			{
				sprintf(buf, "%s advanced %d level%s to level %d.",
						GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch));
				mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE);
			}
		}
		else if (gain < 0)
		{
// Pereplut: глупый участок кода.
//			gain = MAX(-max_exp_loss_pc(ch), gain);	// Cap max exp lost per death
//			GET_EXP(ch) += gain;
//			if (GET_EXP(ch) < 0)
//				GET_EXP(ch) = 0;
			while (GET_LEVEL(ch) > 1 && GET_EXP(ch) < level_exp(ch, GET_LEVEL(ch)))
			{
				ch->set_level(ch->get_level() - 1);
				num_levels++;
				sprintf(buf,
						"%sВы потеряли уровень!%s\r\n",
						CCIRED(ch, C_NRM), CCNRM(ch, C_NRM));
				send_to_char(buf, ch);
				decrease_level(ch);
				is_altered = TRUE;
			}
			if (is_altered)
			{
				sprintf(buf, "%s decreases %d level%s to level %d.",
						GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch));
				mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE);
			}
		}

	}
}
Exemple #2
0
/*
 * delete_ - recursively delete X in T.
 *
 * if X is right at T, right(T) = deleted right(T).
 * if X is left at T, left(T) = deleted lett(T).
 *
 * if X is T, change X and its successor/predecessor
 * and goto childs.
 *
 * after delete, re-balance AA tree.
 *
 */
FREE delete_(void* X, FREE T)
{
	FREE P = T;
	if(!T) return T;
	else if ((FSIZE(X) > FSIZE(T)) || ((FSIZE(X) == FSIZE(T)) && X > T))
	{
		right(T) = delete_(X, right(T));
	}
	else if (X != T)
	{
		left(T) = delete_(X, left(T));
	}
	else
	{
		if (!left(T) && !right(T))
		{
			if(!parent(T))
			{
				address_tree = NULL;
			}
			else if (left(parent(T)) == T)
			{
				left(parent(T)) = NULL;
			}
			else
			{
				right(parent(T)) = NULL;
			}
			return NULL;
		}else if (!left(T))
		{
			P = change_successor(T);
			right(P) = delete_(X, right(P));
		}else
		{
			P = change_predecessor(T);
			left(P) = delete_(X, left(P));
		}
	}
	T = P;
	T = decrease_level(T);
	T = skew(T);
	right(T) = skew(right(T));

	if(right(T)){
		right(right(T)) = skew(right(right(T)));
	}
	T = split(T);
	right(T) = split(right(T));
	return T;
	
}
Exemple #3
0
static int bstree_node_remove( bstree bst, unsigned int *node,
			       KEYTYPE key, VALUETYPE *value){
  unsigned int swap_node;
  VALUETYPE tmp;
  
  if( *node == NODE_NULL ){
    return BSTREE_FAILURE;
  }
  if( key == bst->array[*node].key){
    *value = bst->array[*node].value;
    status = BSTREE_SUCCESS;
    if( bst->array[*node].left == NODE_NULL && 
	bst->array[*node].right == NODE_NULL ){
      *node = NODE_NULL;
      bst->size--;
      if( ((double) bst->size / (double) bst->array_size) < 0.25 &&
	  bst->array_size > MINSIZE ){
	if( bstree_shrink( bst) == BSTREE_MEM_ERROR){
	  return BSTREE_MEM_ERROR;
	}
      }
      return BSTREE_SUCCESS;
    }
    if( bst->array[*node].left == NODE_NULL ){
      swap_node = successor( bst, *node);
      bst->array[*node].key = bst->array[swap_node].key;
      bst->array[*node].value = bst->array[swap_node].value;
      bstree_node_remove( bst, bst->array[*node].right, 
			  bst->array[swap_node].key, &tmp);
    }else{
      swap_node = predecessor( bst, *node);
      bst->array[*node].key = bst->array[swap_node].key;
      bst->array[*node].value = bst->array[swap_node].value;
      bstree_node_remove( bst, bst->array[*node].left,
			  bst->array[swap_node].key, &tmp);
    }
  }else if( COMP( key, bst->array[*node].key) < 0 ){
    status = bstree_node_remove( bst, &(bst->array[node].left), key, value);
  }else{
    status = bstree_node_insert( bst, &(bst->array[node].right), key, value);
  }
  
  decrease_level( bst, *node);
  skew( bst, node);
  if( bst->array[*node].right != NODE_NULL ){
    skew( bst, &(bst->array[*node].right));
    skew( bst, &(bst->array[bst->array[*node].right].right));
  }
  split( bst, node);
  split( bst, &(bst->array[*node].right));
  return status;
}
Exemple #4
0
/// AA tree remove the node
static onion_dict_node *onion_dict_node_remove(const onion_dict *d, onion_dict_node *node, const char *key){
	if (!node)
		return NULL;
	int cmp=d->cmp(key, node->data.key);
	if (cmp<0){
		node->left=onion_dict_node_remove(d, node->left, key);
		//ONION_DEBUG("%p[%s]->left=%p[%s]",node, node->data.key, node->left, node->left ? node->left->data.key : "NULL");
	}
	else if (cmp>0){
		node->right=onion_dict_node_remove(d, node->right, key);
		//ONION_DEBUG("%p[%s]->right=%p[%s]",node, node->data.key, node->right, node->right ? node->right->data.key : "NULL");
	}
	else{ // Real remove
		//ONION_DEBUG("Remove here %p", node);
		onion_dict_node_data_free(&node->data);
		if (node->left==NULL && node->right==NULL){
			onion_low_free(node);
			return NULL;
		}
		if (node->left==NULL){
			onion_dict_node *t=node->right; // Get next key node
			while (t->left) t=t->left;
			//ONION_DEBUG("Set data from %p[%s] to %p[already deleted %s]",t,t->data.key, node, key);
			memcpy(&node->data, &t->data, sizeof(onion_dict_node_data));
			t->data.flags=0; // No double free later, please
			node->right=onion_dict_node_remove(d, node->right, t->data.key);
			//ONION_DEBUG("%p[%s]->right=%p[%s]",node, node->data.key, node->right, node->right ? node->right->data.key : "NULL");
		}
		else{
			onion_dict_node *t=node->left; // Get prev key node
			while (t->right) t=t->right;

			memcpy(&node->data, &t->data, sizeof(onion_dict_node_data));
			t->data.flags=0; // No double free later, please
			node->left=onion_dict_node_remove(d, node->left, t->data.key);
			//ONION_DEBUG("%p[%s]->left=%p[%s]",node, node->data.key, node->left, node->left ? node->left->data.key : "NULL");
		}
	}
	decrease_level(node);
	node=skew(node);
	if (node->right){
		node->right=skew(node->right);
		if (node->right->right)
			node->right->right=skew(node->right->right);
	}
	node=split(node);
	if (node->right)
		node->right=split(node->right);
	return node;
}
Exemple #5
0
void gain_exp(CHAR_DATA * ch, int gain)
{
	int is_altered = FALSE;
	int num_levels = 0;
	char buf[128];

	if (IS_NPC(ch))
	{
		ch->set_exp(ch->get_exp() + gain);
		return;
	}
	else
	{
		ch->dps_add_exp(gain);
		ZoneExpStat::add(zone_table[world[IN_ROOM(ch)]->zone].number, gain);
	}

	if (!IS_NPC(ch) && ((GET_LEVEL(ch) < 1 || GET_LEVEL(ch) >= LVL_IMMORT)))
		return;

	if (gain > 0 && GET_LEVEL(ch) < LVL_IMMORT)
	{
		gain = MIN(max_exp_gain_pc(ch), gain);	// put a cap on the max gain per kill
		ch->set_exp(ch->get_exp() + gain);
		if (GET_EXP(ch) >= level_exp(ch, LVL_IMMORT))
		{
			if (!GET_GOD_FLAG(ch, GF_REMORT) && GET_REMORT(ch) < MAX_REMORT)
			{
				if (Remort::can_remort_now(ch))
				{
					send_to_char(ch, "%sПоздравляем, вы получили право на перевоплощение!%s\r\n",
						CCIGRN(ch, C_NRM), CCNRM(ch, C_NRM));
				}
				else
				{
					send_to_char(ch,
						"%sПоздравляем, вы набрали максимальное количество опыта!\r\n"
						"%s%s\r\n", CCIGRN(ch, C_NRM), Remort::WHERE_TO_REMORT_STR.c_str(), CCNRM(ch, C_NRM));
				}
				SET_GOD_FLAG(ch, GF_REMORT);
			}
		}
		ch->set_exp(MIN(GET_EXP(ch), level_exp(ch, LVL_IMMORT) - 1));
		while (GET_LEVEL(ch) < LVL_IMMORT && GET_EXP(ch) >= level_exp(ch, GET_LEVEL(ch) + 1))
		{
			ch->set_level(ch->get_level() + 1);
			num_levels++;
			sprintf(buf, "%sВы достигли следующего уровня!%s\r\n", CCWHT(ch, C_NRM), CCNRM(ch, C_NRM));
			send_to_char(buf, ch);
			advance_level(ch);
			is_altered = TRUE;
		}

		if (is_altered)
		{
			sprintf(buf, "%s advanced %d level%s to level %d.",
					GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch));
			mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE);
		}
	}
	else if (gain < 0 && GET_LEVEL(ch) < LVL_IMMORT)
	{
		gain = MAX(-max_exp_loss_pc(ch), gain);	// Cap max exp lost per death
		ch->set_exp(ch->get_exp() + gain);
		while (GET_LEVEL(ch) > 1 && GET_EXP(ch) < level_exp(ch, GET_LEVEL(ch)))
		{
			ch->set_level(ch->get_level() - 1);
			num_levels++;
			sprintf(buf,
					"%sВы потеряли уровень. Вам должно быть стыдно!%s\r\n",
					CCIRED(ch, C_NRM), CCNRM(ch, C_NRM));
			send_to_char(buf, ch);
			decrease_level(ch);
			is_altered = TRUE;
		}
		if (is_altered)
		{
			sprintf(buf, "%s decreases %d level%s to level %d.",
					GET_NAME(ch), num_levels, num_levels == 1 ? "" : "s", GET_LEVEL(ch));
			mudlog(buf, BRF, LVL_IMPL, SYSLOG, TRUE);
		}
	}
	if ((GET_EXP(ch) < level_exp(ch, LVL_IMMORT) - 1)
		&& GET_GOD_FLAG(ch, GF_REMORT)
		&& gain
		&& (GET_LEVEL(ch) < LVL_IMMORT))
	{
		if (Remort::can_remort_now(ch))
		{
			send_to_char(ch, "%sВы потеряли право на перевоплощение!%s\r\n",
				CCIRED(ch, C_NRM), CCNRM(ch, C_NRM));
		}
		CLR_GOD_FLAG(ch, GF_REMORT);
	}

	char_stat::add_class_exp(GET_CLASS(ch), gain);
	update_clan_exp(ch, gain);
}