Esempio n. 1
0
/*
	\command set
	\description Change properties of characters and items.
	\usage - <code>set key value</code>
	Key is the name of the property you want to set.
	Value is the new property value.
	\notes See the object reference for <object id="char">characters</object> 
	and <object id="item">items</object> for valid property keys. All integer, float, string, 
	character and item properties can be set using this command as well. In addition to the 
	properties you find there, you can also set skills by using skill.skillname as the key and 
	the skill value multiplied by ten as the value (i.e. 100.0% = 1000).
*/
void commandSet( cUOSocket *socket, const QString &command, const QStringList &args ) throw()
{
	Q_UNUSED(command);
	if( args.size() < 1 )
	{
		socket->sysMessage( "Usage: set <key> <value>" );
		return;
	}

	QString key = args[0];
	QStringList realargs(args);
	realargs.remove(realargs.begin());
	QString value;
	if (realargs.size() == 0) 
	{
		value = "";
	}
	else
	{
		value = realargs.join(" ");
	}

	// Alias for speed sake on setting stats.
	if( key == "str" )
	{
		socket->sysMessage( tr( "Please select a target to 'set %1 %2' " ).arg( "strength" ).arg( value ) );
		socket->attachTarget( new cSetTarget( "strength", value ) );
	}
	else if( key == "dex" )
	{
		socket->sysMessage( tr( "Please select a target to 'set %1 %2' " ).arg( "dexterity" ).arg( value ) );
		socket->attachTarget( new cSetTarget( "dexterity", value ) );
	}
	else if( key == "int" )
	{
		socket->sysMessage( tr( "Please select a target to 'set %1 %2' " ).arg( "intelligence" ).arg( value ) );
		socket->attachTarget( new cSetTarget( "intelligence", value ) );
	}
	else
	{
		socket->sysMessage( tr( "Please select a target to 'set %1 %2' " ).arg( key ).arg( value ) );
		socket->attachTarget( new cSetTarget( key, value ) );
	}
}
std::function<variant_type(const std::vector<variant_type>&)> 
toolkit_function_registry::get_native_function(const function_closure_info& closure) {
  const auto* toolkit_fn_spec = get_toolkit_function_info(closure.native_fn_name);
  // basic error checking. 
  if (toolkit_fn_spec == nullptr) {
    throw std::string("toolkit function " + closure.native_fn_name + " not found");
    return nullptr;
  }
  if (toolkit_fn_spec->native_execute_function == nullptr) {
    throw std::string("toolkit function " + closure.native_fn_name + 
                      " cannot be run as a native lambda since it was not"
                      " compiled and registered using the SDK registration scheme.");
    return nullptr;
  }
  // now. we need to wrap the closure
  // some basic checking to make sure the closure is complete
  if (closure.arguments.size() != toolkit_fn_spec->description.at("arguments").size()) {
    throw std::string("Incomplete closure specified for toolkit function " + 
                      closure.native_fn_name);
  }

  // first fast path for the identity case
  bool is_fast_path = true;
  for (size_t i = 0;i < closure.arguments.size(); ++i) {
    // every argument is a parameter matching the input ordering
    if (!(closure.arguments[i].first == function_closure_info::PARAMETER &&
        closure.arguments[i].second->which() == 0 &&
        variant_get_value<size_t>(*(closure.arguments[i].second)) == i)) {
      is_fast_path = false;
      break;
    }
  }
  // identity call. no transformation needed
  if (is_fast_path) {
    return toolkit_fn_spec->native_execute_function;
  } 
  // how many arguments are there really after the closure application
  int real_num_args = -1;
  for (size_t i = 0;i < closure.arguments.size(); ++i) {
    if (closure.arguments[i].first == function_closure_info::PARAMETER) {
      int argnum = variant_get_value<int>(*(closure.arguments[i].second));
      real_num_args = std::max(real_num_args, argnum);
    }
  }
  ++real_num_args;
  // more complicated path. we need to build up a lambda
  auto native_execute_function = toolkit_fn_spec->native_execute_function;
   
  auto retlambda = 
      [real_num_args,native_execute_function,closure](const std::vector<variant_type>& inargs)->variant_type {
        if (inargs.size() < (size_t)real_num_args) {
          throw std::string("Wrong number of arguments");
        }
        std::vector<variant_type> realargs(closure.arguments.size());
        for (size_t i = 0;i < closure.arguments.size(); ++i) {
          if (closure.arguments[i].first == function_closure_info::CAPTURED_VALUE) {
            realargs[i] = *(closure.arguments[i].second);
          } else {
            int index = variant_get_value<int>(*(closure.arguments[i].second));
            realargs[i] = inargs[index];
          }
        }
        return native_execute_function(realargs);
      };
  return retlambda;
}