Example #1
0
File: group.c Project: nickg/nvc
static void group_decl(tree_t decl, group_nets_ctx_t *ctx, int start, int n)
{
   netid_t first = NETID_INVALID;
   unsigned len = 0;
   type_t type = tree_type(decl);
   const int nnets = tree_nets(decl);
   const bool record = group_contains_record(type);
   int ffield = -1;
   assert((n == -1) | (start + n <= nnets));
   for (int i = start; i < (n == -1 ? nnets : start + n); i++) {
      netid_t nid = tree_net(decl, i);
      if (first == NETID_INVALID) {
         first  = nid;
         len    = 1;
         ffield = record ? group_net_to_field(type, i) : -1;
      }
      else if (nid == first + len
               && (!record || group_net_to_field(type, i) == ffield))
         ++len;
      else {
         group_add(ctx, first, len);
         first  = nid;
         len    = 1;
         ffield = record ? group_net_to_field(type, i) : -1;
      }
   }

   if (first != NETID_INVALID)
      group_add(ctx, first, len);
   else {
      // Array signal with null range
      tree_add_attr_int(decl, null_range_i, 1);
   }
}
Example #2
0
/*
 * Class callback when a CPU becomes active (online)
 *
 * This is called in a context where CPUs are paused
 */
static void
pg_cmt_cpu_active(cpu_t *cp)
{
	int		err;
	group_iter_t	i;
	pg_cmt_t	*pg;
	group_t		*pgs;

	ASSERT(MUTEX_HELD(&cpu_lock));

	if (cmt_sched_disabled)
		return;

	pgs = &cp->cpu_pg->pgs;
	group_iter_init(&i);

	/*
	 * Iterate over the CPU's PGs
	 */
	while ((pg = group_iterate(pgs, &i)) != NULL) {

		if (IS_CMT_PG(pg) == 0)
			continue;

		err = group_add(&pg->cmt_cpus_actv, cp, GRP_NORESIZE);
		ASSERT(err == 0);

		/*
		 * If this is the first active CPU in the PG, and it
		 * represents a hardware sharing relationship over which
		 * CMT load balancing is performed, add it as a candidate
		 * for balancing with it's siblings.
		 */
		if (GROUP_SIZE(&pg->cmt_cpus_actv) == 1 &&
		    (pg->cmt_policy & (CMT_BALANCE | CMT_COALESCE))) {
			err = group_add(pg->cmt_siblings, pg, GRP_NORESIZE);
			ASSERT(err == 0);

			/*
			 * If this is a top level PG, add it as a balancing
			 * candidate when balancing within the root lgroup.
			 */
			if (pg->cmt_parent == NULL &&
			    pg->cmt_siblings != &cmt_root->cl_pgs) {
				err = group_add(&cmt_root->cl_pgs, pg,
				    GRP_NORESIZE);
				ASSERT(err == 0);
			}
		}

		/*
		 * Notate the CPU in the PGs active CPU bitset.
		 * Also notate the PG as being active in it's associated
		 * partition
		 */
		bitset_add(&pg->cmt_cpus_actv_set, cp->cpu_seqid);
		bitset_add(&cp->cpu_part->cp_cmt_pgs, ((pg_t *)pg)->pg_id);
	}
}
Example #3
0
File: group.c Project: nickg/nvc
static void ungroup_proc_params(tree_t t, group_nets_ctx_t *ctx)
{
   // Ungroup any signal that is passed to a procedure as in general we
   // cannot guarantee anything about the procedure's behaviour

   const int nparams = tree_params(t);
   for (int i = 0; i < nparams; i++) {
      tree_t value = tree_value(tree_param(t, i));

      tree_kind_t kind = tree_kind(value);
      while (kind == T_ARRAY_REF || kind == T_ARRAY_SLICE) {
         value = tree_value(value);
         kind = tree_kind(value);
      }

      if (kind != T_REF)
         continue;

      tree_t decl = tree_ref(value);

      if (tree_kind(decl) != T_SIGNAL_DECL)
         continue;

      const int nnets = tree_nets(decl);
      for (int i = 0; i < nnets; i++)
         group_add(ctx, tree_net(decl, i), 1);
   }
}
Example #4
0
static void cb_group_invite(Tox *m, int32_t friendnumber, uint8_t type, const uint8_t *group_pub_key, uint16_t length,
                            void *userdata)
{
    if (!friend_is_master(m, friendnumber))
        return;

    char name[TOX_MAX_NAME_LENGTH];
    tox_friend_get_name(m, friendnumber, (uint8_t *) name, NULL);
    size_t len = tox_friend_get_name_size(m, friendnumber, NULL);
    name[len] = '\0';

    int groupnum = -1;

    if (type == TOX_GROUPCHAT_TYPE_TEXT)
        groupnum = tox_join_groupchat(m, friendnumber, group_pub_key, length);
    else if (type == TOX_GROUPCHAT_TYPE_AV)
        groupnum = toxav_join_av_groupchat(m, friendnumber, group_pub_key, length, NULL, NULL);

    if (groupnum == -1) {
        fprintf(stderr, "Invite from %s failed (core failure)\n", name);
        return;
    }

    if (group_add(groupnum, type, NULL) == -1) {
        fprintf(stderr, "Invite from %s failed (group_add failed)\n", name);
        tox_del_groupchat(m, groupnum);
        return;
    }

    printf("Accepted groupchat invite from %s [%d]\n", name, groupnum);
}
Example #5
0
void	CPHGeometryOwner::add_geom( CODEGeom* g )
{
	VERIFY( b_builded );
	VERIFY( m_group );
	m_geoms.push_back( g );
	group_add( *g );
	//g->add_to_space( m_group );
}
Example #6
0
File: group.c Project: nickg/nvc
static void ungroup_ref(tree_t target, group_nets_ctx_t *ctx)
{
   tree_t decl = tree_ref(target);
   if (tree_kind(decl) == T_SIGNAL_DECL) {
      const int nnets = tree_nets(decl);
      for (int i = 0; i < nnets; i++)
         group_add(ctx, tree_net(decl, i), 1);
   }
}
Example #7
0
/* recursively adds a group given its number -- uses group_add */
void gn_add( CHAR_DATA *ch, int gn)
{
    int i;

    ch->pcdata->group_known[gn] = TRUE;
    for ( i = 0; i < MAX_IN_GROUP; i++)
    {
        if (group_table[gn].spells[i] == NULL)
            break;
        group_add(ch,group_table[gn].spells[i],FALSE);
    }
}
Example #8
0
void CPHGeometryOwner::			build_Geom	(CODEGeom& geom)
{

	geom.build(m_mass_center);
	//geom.set_body(m_body);
	geom.set_material(ul_material);
	if(contact_callback)geom.set_contact_cb(contact_callback);
	if(object_contact_callback)geom.set_obj_contact_cb(object_contact_callback);
	if(m_phys_ref_object) geom.set_ref_object(m_phys_ref_object);
	//VERIFY( m_group );
	group_add( geom );

}
Example #9
0
int TcWebApiAdv_vlan_group_execute(int id)
{
		int i;
		if(id==GB_C_VLAN_GROUPSETTING)
		{fprintf(stderr,"-----save\n");
			group_del();
			group_add();
		}



		if(id==GB_C_VLAN_GROUPDELETE)
		{
			strncpy(bu_active,web_api->adv_vlan_group[vlan_index-1]->active,8);
			strncpy(web_api->adv_vlan_group[vlan_index-1]->active,val_def->vlan_group_active_no,8);	
			
			strncpy(bu_vlan_id,web_api->adv_vlan_group[vlan_index-1]->vlan_id,8);
			memset(web_api->adv_vlan_group[vlan_index-1]->vlan_id,0,sizeof(web_api->adv_vlan_group[vlan_index-1]->vlan_id));
			
			for(i=0;i<8;i++)
			{
				bu_atmt[i]=web_api->adv_vlan_group[vlan_index-1]->atmt[i];
				web_api->adv_vlan_group[vlan_index-1]->atmt[i]=0;
				
				bu_atmp[i]=web_api->adv_vlan_group[vlan_index-1]->atmp[i];
				web_api->adv_vlan_group[vlan_index-1]->atmp[i]=0;
			}
			for(i=0;i<4;i++)
			{
				bu_ethernett[i]=web_api->adv_vlan_group[vlan_index-1]->ethernett[i];
				web_api->adv_vlan_group[vlan_index-1]->ethernett[i]=0;
				
				bu_ethernetp[i]=web_api->adv_vlan_group[vlan_index-1]->ethernetp[i];
				web_api->adv_vlan_group[vlan_index-1]->ethernetp[i]=0;
			}
			bu_usbt=web_api->adv_vlan_group[vlan_index-1]->usbt;
			web_api->adv_vlan_group[vlan_index-1]->usbt=0;
			
			bu_usbp=web_api->adv_vlan_group[vlan_index-1]->usbp;
			web_api->adv_vlan_group[vlan_index-1]->usbp=0;	
	
			group_del();
		}

	group_write();
	return 0;
}
Example #10
0
/* this procedure handles the input parsing for the skill generator */
bool parse_gen_groups(CHAR_DATA *ch,const char *argument) {
  char arg[MAX_INPUT_LENGTH];
  char buf[100];
  int gn,sn,i;

  if (argument[0] == '\0')
    return FALSE;

  argument = one_argument(argument,arg);

  if (!str_prefix(arg,"help")) {
    if (argument[0] == '\0') {
      do_help(ch,"group help");
      return TRUE;
    }
    
    do_help(ch,argument);
    return TRUE;
  }

  // Removed by SinaC 2001, replaced with help
  /*
  // Added by Sinac 1997
  if (!str_prefix(arg,"level")) {
    do_level(ch,argument);
    return TRUE;
  }
  */

  // Added by SinaC 2001, so spells can be gained one by one not only by group
  if (!str_prefix(arg,"spell")) {
    list_spell_costs(ch);
    return TRUE;
  }

  // Added by SinaC 2001, so powers can be gained one by one not only by group
  if (!str_prefix(arg,"power")) {
    list_power_costs(ch);
    return TRUE;
  }

  // Added by SinaC 2003
  if (!str_prefix(arg,"song")) {
    list_song_costs(ch);
    return TRUE;
  }

  if (!str_prefix(arg,"add")) {
    if (argument[0] == '\0') {
      send_to_char("You must provide a skill/spell or group name.\n\r",ch);
      return TRUE;
    }
    
    gn = group_lookup(argument);
    if (gn != -1) {
      if (ch->gen_data->group_chosen[gn]
	  ||  ch->pcdata->group_known[gn]) {
	send_to_char("You already know that group!\n\r",ch);
	return TRUE;
      }
      
      if (class_grouprating( ch->bstat(classes), gn ) <= 0
	  || god_grouprating( ch, gn ) <= 0 ) {
	send_to_char("That group is not available.\n\r",ch);
	return TRUE;
      }
    
      sprintf(buf,"{W%s group added.{x\n\r",group_table[gn].name);
      send_to_char(buf,ch);
      ch->gen_data->group_chosen[gn] = TRUE;
      ch->gen_data->points_chosen += class_grouprating( ch->bstat(classes), gn );
      gn_add(ch,gn);
      ch->pcdata->points += class_grouprating( ch->bstat(classes), gn );
      return TRUE;
    }
    
    sn = ability_lookup(argument);
    if (sn != -1) {
      // Modified by SinaC 2001 for god skill
      if (ch->gen_data->ability_chosen[sn]
	  || get_raceability( ch, sn )
	  || get_clanability( ch, sn )
	  /*|| get_godskill( ch, sn )  removed by SinaC 2003*/
	  ||  ch->pcdata->ability_info[sn].learned > 0) {
	send_to_char("You already know that skill/spell/power/song!\n\r",ch);
	return TRUE;
      }
      
      // Modified by SinaC 2003
      if (class_gainabilityrating(ch, sn, ch->pcdata->ability_info[sn].casting_level ) <= 0
	  // Removed by SinaC 2001 so spells can be gained one by one
	  //  not only by group
	  /*||  ability_table[sn].spell_fun != spell_null*/) {
	send_to_char("That skill/spell/power/song is not available.\n\r",ch);
	return TRUE;
      }

      // Added by SinaC 2001
      if ( !can_gain_creation( ch, sn ) ) {
 	send_to_charf( ch, "You don't fit the prereqs for %s.\n\r",
		       ability_table[sn].name);
	return TRUE;
      }


      sprintf(buf, "{W%s skill/spell/power/song added.{x\n\r",ability_table[sn].name);
      send_to_char(buf,ch);
      ch->gen_data->ability_chosen[sn] = TRUE;
      ch->gen_data->points_chosen += class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level );
      //ch->pcdata->ability_info[sn].learned = 1;  SinaC 2003, casting level need to be set
      group_add( ch, ability_table[sn].name, FALSE );
      ch->pcdata->points += class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level );
      return TRUE;
    }
    
    send_to_char("No skills/spells/powers/songs or groups by that name...\n\r",ch);
    return TRUE;
  }
  
  if (!str_cmp(arg,"drop")) {
    if (argument[0] == '\0') {
      send_to_char("You must provide a skill/spell/power/song or group to drop.\n\r",ch);
      return TRUE;
    }

    gn = group_lookup(argument);
    if (gn != -1 && ch->gen_data->group_chosen[gn]) {
      send_to_char("{WGroup dropped.{x\n\r",ch);
      ch->gen_data->group_chosen[gn] = FALSE;
      ch->gen_data->points_chosen -= class_grouprating( ch->bstat(classes), gn );
      gn_remove(ch,gn);
      for (i = 0; i < MAX_GROUP; i++) {
	if (ch->gen_data->group_chosen[gn])
	  gn_add(ch,gn);
      }
      ch->pcdata->points -= class_grouprating( ch->bstat(classes), gn );
      // To avoid losing basic abilities which would be included in the group we just removed
      //  we re-add basics
      group_add( ch, class_table[ class_firstclass( ch->bstat(classes) ) ].base_group, FALSE );
      return TRUE;
    }
    
    sn = ability_lookup(argument);
    if (sn != -1 && ch->gen_data->ability_chosen[sn]) {
      send_to_char("{WSkill/spell/power/song dropped.{x\n\r",ch);
      ch->gen_data->ability_chosen[sn] = FALSE;
      ch->gen_data->points_chosen -= class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level );
      ch->pcdata->ability_info[sn].learned = 0;
      ch->pcdata->points -= class_abilityrating( ch, sn, ch->pcdata->ability_info[sn].casting_level );
      return TRUE;
    }
    
    send_to_char("You haven't bought any such skill/spell/power/song or group.\n\r",ch);
    return TRUE;
  }
  
  if (!str_prefix(arg,"premise")) {
    do_help(ch,"premise");
    return TRUE;
  }
  
  if (!str_prefix(arg,"list")) {
    list_group_costs(ch);
    return TRUE;
  }
  
  if (!str_prefix(arg,"learned")) {
    list_group_chosen(ch);
    return TRUE;
  }

  // Added by SinaC 2000
  if (!str_prefix(arg,"known")){
    list_group_known(ch);
  }
  
  if (!str_prefix(arg,"info")) {
    do_groups(ch,argument);
    return TRUE;
  }

  return FALSE;
}
Example #11
0
/*
 * Promote PG above it's current parent.
 * This is only legal if PG has an equal or greater number of CPUs than its
 * parent.
 *
 * This routine operates on the CPU specific processor group data (for the CPUs
 * in the PG being promoted), and may be invoked from a context where one CPU's
 * PG data is under construction. In this case the argument "pgdata", if not
 * NULL, is a reference to the CPU's under-construction PG data.
 */
static void
cmt_hier_promote(pg_cmt_t *pg, cpu_pg_t *pgdata)
{
	pg_cmt_t	*parent;
	group_t		*children;
	cpu_t		*cpu;
	group_iter_t	iter;
	pg_cpu_itr_t	cpu_iter;
	int		r;
	int		err;

	ASSERT(MUTEX_HELD(&cpu_lock));

	parent = pg->cmt_parent;
	if (parent == NULL) {
		/*
		 * Nothing to do
		 */
		return;
	}

	ASSERT(PG_NUM_CPUS((pg_t *)pg) >= PG_NUM_CPUS((pg_t *)parent));

	/*
	 * We're changing around the hierarchy, which is actively traversed
	 * by the dispatcher. Pause CPUS to ensure exclusivity.
	 */
	pause_cpus(NULL);

	/*
	 * If necessary, update the parent's sibling set, replacing parent
	 * with PG.
	 */
	if (parent->cmt_siblings) {
		if (group_remove(parent->cmt_siblings, parent, GRP_NORESIZE)
		    != -1) {
			r = group_add(parent->cmt_siblings, pg, GRP_NORESIZE);
			ASSERT(r != -1);
		}
	}

	/*
	 * If the parent is at the top of the hierarchy, replace it's entry
	 * in the root lgroup's group of top level PGs.
	 */
	if (parent->cmt_parent == NULL &&
	    parent->cmt_siblings != &cmt_root->cl_pgs) {
		if (group_remove(&cmt_root->cl_pgs, parent, GRP_NORESIZE)
		    != -1) {
			r = group_add(&cmt_root->cl_pgs, pg, GRP_NORESIZE);
			ASSERT(r != -1);
		}
	}

	/*
	 * We assume (and therefore assert) that the PG being promoted is an
	 * only child of it's parent. Update the parent's children set
	 * replacing PG's entry with the parent (since the parent is becoming
	 * the child). Then have PG and the parent swap children sets.
	 */
	ASSERT(GROUP_SIZE(parent->cmt_children) <= 1);
	if (group_remove(parent->cmt_children, pg, GRP_NORESIZE) != -1) {
		r = group_add(parent->cmt_children, parent, GRP_NORESIZE);
		ASSERT(r != -1);
	}

	children = pg->cmt_children;
	pg->cmt_children = parent->cmt_children;
	parent->cmt_children = children;

	/*
	 * Update the sibling references for PG and it's parent
	 */
	pg->cmt_siblings = parent->cmt_siblings;
	parent->cmt_siblings = pg->cmt_children;

	/*
	 * Update any cached lineages in the per CPU pg data.
	 */
	PG_CPU_ITR_INIT(pg, cpu_iter);
	while ((cpu = pg_cpu_next(&cpu_iter)) != NULL) {
		int		idx;
		pg_cmt_t	*cpu_pg;
		cpu_pg_t	*pgd;	/* CPU's PG data */

		/*
		 * The CPU's whose lineage is under construction still
		 * references the bootstrap CPU PG data structure.
		 */
		if (pg_cpu_is_bootstrapped(cpu))
			pgd = pgdata;
		else
			pgd = cpu->cpu_pg;

		/*
		 * Iterate over the CPU's PGs updating the children
		 * of the PG being promoted, since they have a new parent.
		 */
		group_iter_init(&iter);
		while ((cpu_pg = group_iterate(&pgd->cmt_pgs, &iter)) != NULL) {
			if (cpu_pg->cmt_parent == pg) {
				cpu_pg->cmt_parent = parent;
			}
		}

		/*
		 * Update the CMT load balancing lineage
		 */
		if ((idx = group_find(&pgd->cmt_pgs, (void *)pg)) == -1) {
			/*
			 * Unless this is the CPU who's lineage is being
			 * constructed, the PG being promoted should be
			 * in the lineage.
			 */
			ASSERT(pg_cpu_is_bootstrapped(cpu));
			continue;
		}

		ASSERT(GROUP_ACCESS(&pgd->cmt_pgs, idx - 1) == parent);
		ASSERT(idx > 0);

		/*
		 * Have the child and the parent swap places in the CPU's
		 * lineage
		 */
		group_remove_at(&pgd->cmt_pgs, idx);
		group_remove_at(&pgd->cmt_pgs, idx - 1);
		err = group_add_at(&pgd->cmt_pgs, parent, idx);
		ASSERT(err == 0);
		err = group_add_at(&pgd->cmt_pgs, pg, idx - 1);
		ASSERT(err == 0);
	}

	/*
	 * Update the parent references for PG and it's parent
	 */
	pg->cmt_parent = parent->cmt_parent;
	parent->cmt_parent = pg;

	start_cpus();
}
Example #12
0
static void cmd_group(Tox *m, uint32_t friendnum, int argc, char (*argv)[MAX_COMMAND_LENGTH])
{
    const char *outmsg = NULL;

    if (argc < 1) {
        outmsg = "Please specify the group type: audio or text";
        tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL);
        return;
    }

    uint8_t type = TOX_CONFERENCE_TYPE_AV ? !strcasecmp(argv[1], "audio") : TOX_CONFERENCE_TYPE_TEXT;

    char name[TOX_MAX_NAME_LENGTH];
    tox_friend_get_name(m, friendnum, (uint8_t *) name, NULL);
    size_t len = tox_friend_get_name_size(m, friendnum, NULL);
    name[len] = '\0';

    int groupnum = -1;

    if (type == TOX_CONFERENCE_TYPE_TEXT) {
        TOX_ERR_CONFERENCE_NEW err;
        groupnum = tox_conference_new(m, &err);

        if (err != TOX_ERR_CONFERENCE_NEW_OK) {
            printf("Group chat creation by %s failed to initialize\n", name);
            outmsg = "Group chat instance failed to initialize.";
            tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL);
            return;
        }
    } else if (type == TOX_CONFERENCE_TYPE_AV) {
        groupnum = toxav_add_av_groupchat(m, NULL, NULL);

        if (groupnum == -1) {
            printf("Group chat creation by %s failed to initialize\n", name);
            outmsg = "Group chat instance failed to initialize.";
            tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL);
            return;
        }
    }

    const char *password = argc >= 2 ? argv[2] : NULL;

    if (password && strlen(argv[2]) >= MAX_PASSWORD_SIZE) {
        printf("Group chat creation by %s failed: Password too long\n", name);
        outmsg = "Group chat instance failed to initialize: Password too long";
        tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL);
        return;
    }

    if (group_add(groupnum, type, password) == -1) {
        printf("Group chat creation by %s failed\n", name);
        outmsg = "Group chat creation failed";
        tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) outmsg, strlen(outmsg), NULL);
        tox_conference_delete(m, groupnum, NULL);
        return;
    }

    const char *pw = password ? " (Password protected)" : "";
    printf("Group chat %d created by %s%s\n", groupnum, name, pw);

    char msg[MAX_COMMAND_LENGTH];
    snprintf(msg, sizeof(msg), "Group chat %d created%s", groupnum, pw);
    tox_friend_send_message(m, friendnum, TOX_MESSAGE_TYPE_NORMAL, (uint8_t *) msg, strlen(msg), NULL);
}
Example #13
0
File: group.c Project: nickg/nvc
static groupid_t group_add(group_nets_ctx_t *ctx, netid_t first, int length)
{
   assert(length > 0);
   assert(first < ctx->nnets);
   assert(first + length <= ctx->nnets);

   for (netid_t i = first; i < first + length; i++) {
      group_t *it = ctx->lookup[i];
      if (it == NULL || it->gid == GROUPID_INVALID)
         continue;

      if ((it->first == first) && (it->length == length)) {
         // Exactly matches
         return it->gid;
      }
      else if (it->first >= first + length) {
         // Disjoint, to the right
      }
      else if (first >= it->first + it->length) {
         // Disjoint, to the left
      }
      else if ((first == it->first) && (length > it->length)) {
         // Overlaps on left
         group_add(ctx, first + it->length, length - it->length);
         return GROUPID_INVALID;
      }
      else if ((first > it->first)
               && (first + length == it->first + it->length)) {
         // Overlaps on right
         group_unlink(ctx, it);
         group_add(ctx, it->first, first - it->first);
         group_reuse(ctx, it);
         return group_alloc(ctx, first, length);
      }
      else if ((first > it->first)
               && (first + length < it->first + it->length)) {
         // Overlaps completely
         group_unlink(ctx, it);
         group_add(ctx, it->first, first - it->first);
         group_add(ctx, first + length,
                   it->first + it->length - first - length);
         group_reuse(ctx, it);
         return group_alloc(ctx, first, length);
      }
      else if ((first < it->first)
               && (first + length > it->first + it->length)) {
         // Contains in middle
         group_add(ctx, first, it->first - first);
         group_add(ctx, it->first + it->length,
                   first + length - it->first - it->length);
         return GROUPID_INVALID;
      }
      else if ((first == it->first)
               && (first + length < it->first + it->length)) {
         // Contains on left
         group_unlink(ctx, it);
         group_add(ctx, first + length, it->length - length);
         group_reuse(ctx, it);
         return group_alloc(ctx, first, length);
      }
      else if ((first < it->first)
               && (first + length == it->first + it->length)) {
         // Contains on right
         group_add(ctx, first, it->first - first);
         return GROUPID_INVALID;
      }
      else if ((first < it->first) && (first + length > it->first)) {
         // Split left
         group_unlink(ctx, it);
         group_add(ctx, first, it->first - first);
         group_add(ctx, it->first, first + length - it->first);
         group_add(ctx, first + length,
                   it->first + it->length - first - length);
         group_reuse(ctx, it);
         return GROUPID_INVALID;
      }
      else if ((first > it->first) && (it->first + it->length > first)) {
         // Split right
         group_unlink(ctx, it);
         group_add(ctx, it->first, first - it->first);
         group_add(ctx, first, it->first + it->length - first);
         group_add(ctx, it->first + it->length,
                   first + length - it->first - it->length);
         group_reuse(ctx, it);
         return GROUPID_INVALID;
      }
      else
         fatal("unhandled case in group_add: first=%d length=%d "
               "it->first=%d it->length=%d", first, length,
               it->first, it->length);
   }

   return group_alloc(ctx, first, length);
}
Example #14
0
void do_multiclass(CHAR_DATA *ch, const char *argument) {
  int iClass;
  //  char arg[MAX_INPUT_LENGTH];

  ROOM_INDEX_DATA *pRoom;
  OBJ_DATA *obj;

  if (IS_NPC(ch)){
    send_to_char("Mobs can't multiclass!\n\r",ch);
    return;
  }

  if (IS_IMMORTAL(ch)) {
    send_to_char("Immortals are damned to be immortals.\n\r",ch);
    return;
  }

  //  argument = one_argument(argument,arg);

  if (argument[0] == 0) {
    send_to_char("You must provide a class name to add to your class list.\n\r",ch);
    return;
  }

  iClass = class_lookup(argument, TRUE );
  if (iClass == -1) {
    send_to_char("You must provide an existing class name to add to your class list.\n\r",ch);
    return;
  }

  if ((1<<iClass) & ch->bstat(classes)) {
    send_to_char("Choose a class that you don't already have.\n\r",ch);
    return;
  }

  // Added by SinaC 2001
  if ( !check_class_god( iClass, ch->pcdata->god ) ){
    send_to_charf(ch,
		  "%s doesn't allow that class.\n\r",
		  god_name(ch->pcdata->god));
    return;
  }
  if ( !check_class_race( ch, iClass ) ){
    send_to_char( "You can't choose that class because of your race.\n\r", ch );
    return;
  }
  // Added by SinaC 2003 for subclass system
  //  If trying to multiclass in a subclass without having the parent class
  //  Should be able to get only one sub-class for each parent-class
  //   Cannot be fire and water elementalist
  //   Cannot be enchanter and transmuter
  //   But can be assassin and fire elementalist
  if ( class_table[iClass].parent_class != iClass
       && !((1<<class_table[iClass].parent_class) & ch->bstat(classes))) {
    send_to_char("You can't choose this sub-class because you don't have the parent class.\n\r", ch );
    return;
  }
  // Added by SinaC 2003 to determine if a class can be picked during creation/multiclass
  if ( class_table[iClass].choosable != CLASS_CHOOSABLE_YES ) {
    send_to_char("This class cannot be picked.\n\r", ch );
    return;
  }

  // check wild-magic
  if ( ch->isWildMagic                                                    // can't get non-wild magic class
       && IS_SET( class_table[iClass].type, CLASS_MAGIC )                 //  if wild mage
       && !IS_SET( class_table[iClass].type, CLASS_WILDABLE ) ) {
    send_to_charf(ch,"This class cannot be picked by a wild-mage.\n\r");
    return;
  }

  // kill pet and charmies
  die_follower( ch );

  /* Test if fighting ? */
  stop_fighting( ch, TRUE );

  /* Go to donation room */

  pRoom = get_donation_room( ch );
  //pRoom = get_room_index( ROOM_VNUM_DONATION );
  if (pRoom==NULL) {
    bug("do_multiclass: donation room not found for player [%s] clan [%s] hometown [%s]!",
	NAME(ch), get_clan_table(ch->clan)->name,
	(IS_NPC(ch)||ch->pcdata->hometown<0)?"none":hometown_table[ch->pcdata->hometown].name);
    //bug("multiclass: donation room not found %d!",ROOM_VNUM_DONATION);
    return;
  }

  if (ch->in_room != pRoom) {
    act("$n disapears!",ch,NULL,NULL,TO_ROOM);
    char_from_room( ch );
    char_to_room( ch, pRoom );
    act( "$n appears in the donation room.", ch, NULL, NULL, TO_ROOM );
  }

  ch->level = 1;
  ch->bstat(classes) |= 1<<iClass;
  ch->hit = 20;        /* I should place constants instead of "hard code" */
  ch->bstat(max_hit) = 20;
  ch->mana = 100;
  ch->bstat(max_mana) = 100;
  // Added by SinaC 2001 for mental user
  ch->psp = 100;
  ch->bstat(max_psp) = 100;
  ch->move = 100;
  ch->bstat(max_move) = 100;
  ch->wimpy = 0;

  /* ch->pcdata->points = ? creation points*/
  ch->exp = exp_per_level(ch,ch->pcdata->points);

  /* Train - Pra ?*/

  /* Gain base group*/
  group_add(ch,class_table[iClass].base_group,FALSE);

  /*group_add(ch,class_table[iClass].default_group,TRUE);*/
  /* adding this would raise creation points too much*/

  /*group_add(ch,class_table[iClass].default_group,FALSE);*/
  /* adding this would be too easy for the player */

  /* gold & silver ?*/

  /* Dealing with equipment */
  // FIXME: item STAY_DEATH or owned equipement must be dropped ?
  while ( ch->carrying != NULL ) {
    /* Remove the obj if it is worn */
    obj = ch->carrying;
    if (obj->wear_loc != WEAR_NONE)
      unequip_char( ch, obj );

    obj_from_char( obj );
    obj_to_room( obj, pRoom );
    SET_OBJ_STAT( obj, ITEM_DONATED);
  }

  // Added by SinaC 2001
  recompute(ch); 
  // Added by SinaC 2001
  recomproom(pRoom);

  do_outfit(ch,"");

  send_to_char("You are now mortal again...\n\r",ch);
  send_to_char("You see all your possesions lying on the ground...\n\r",ch);
  send_to_char("Probably few things are still usable, you'd better\n\r"
	       "leave them here.\n\r",ch);

  char buf[MAX_INPUT_LENGTH];
  sprintf( buf, "$N has multiclassed in %s.", class_table[iClass].name );
  wiznet(buf, ch, NULL, WIZ_MULTICLASS, 0, 0 );
}
Example #15
0
/*
 * Add a PG to a hwset
 */
static void
pghw_set_add(group_t *hwset, pghw_t *pg)
{
	(void) group_add(hwset, pg, GRP_RESIZE);
}