Пример #1
0
/** Actually change the ownership of something, and fix bits.
 * \param player the enactor.
 * \param thing object to change ownership of.
 * \param newowner new owner for thing.
 * \param preserve if 1, preserve privileges and don't halt.
 */
void
chown_object(dbref player, dbref thing, dbref newowner, int preserve)
{
  (void) undestroy(player, thing);
  if (God(player)) {
    Owner(thing) = newowner;
  } else {
    Owner(thing) = Owner(newowner);
  }
  /* Don't allow circular zones */
  Zone(thing) = NOTHING;
  if (GoodObject(Zone(newowner))) {
    dbref tmp;
    int ok_to_zone = 1;
    int zone_depth = MAX_ZONES;
    for (tmp = Zone(Zone(newowner)); GoodObject(tmp); tmp = Zone(tmp)) {
      if (tmp == thing) {
        notify(player, T("Circular zone broken."));
        ok_to_zone = 0;
        break;
      }
      if (tmp == Zone(tmp)) /* Ran into an object zoned to itself */
        break;
      zone_depth--;
      if (!zone_depth) {
        ok_to_zone = 0;
        notify(player, T("Overly deep zone chain broken."));
        break;
      }
    }
    if (ok_to_zone)
      Zone(thing) = Zone(newowner);
  }
  clear_flag_internal(thing, "CHOWN_OK");
  if (!preserve || !Wizard(player)) {
    clear_flag_internal(thing, "WIZARD");
    clear_flag_internal(thing, "ROYALTY");
    clear_flag_internal(thing, "TRUST");
    set_flag_internal(thing, "HALT");
    destroy_flag_bitmask("POWER", Powers(thing));
    Powers(thing) = new_flag_bitmask("POWER");
    do_halt(thing, "", thing);
  } else {
    if (preserve == 1 && (newowner != player) && Wizard(thing) &&
        !Wizard(newowner)) {
      notify_format(player,
                    T("Warning: WIZ flag reset on #%d because "
                      "@CHOWN/PRESERVE is to a non-WIZ flagged third-party."),
                    thing);
      clear_flag_internal(thing, "WIZARD");
    }
    if (!null_flagmask("POWER", Powers(thing)) || Wizard(thing) ||
        Royalty(thing) || Inherit(thing))
      notify_format(player,
                    T("Warning: @CHOWN/PRESERVE on an object (#%d) "
                      "with WIZ, ROY, INHERIT, or @power privileges."),
                    thing);
  }
}
Пример #2
0
/* Clone an object. The new object is owned by the cloning player */
static dbref
clone_object(dbref player, dbref thing, const char *newname, int preserve)
{
  dbref clone;

  clone = new_object();

  Owner(clone) = Owner(player);
  Name(clone) = NULL;
  if (newname && *newname)
    set_name(clone, newname);
  else
    set_name(clone, Name(thing));
  s_Pennies(clone, Pennies(thing));
  AttrCount(clone) = 0;
  List(clone) = NULL;
  Locks(clone) = NULL;
  clone_locks(player, thing, clone);
  Zone(clone) = Zone(thing);
  Parent(clone) = Parent(thing);
  Flags(clone) = clone_flag_bitmask("FLAG", Flags(thing));
  if (!preserve) {
    clear_flag_internal(clone, "WIZARD");
    clear_flag_internal(clone, "ROYALTY");
    Warnings(clone) = 0;        /* zap warnings */
    Powers(clone) = new_flag_bitmask("POWER");  /* zap powers */
  } else {
    Powers(clone) = clone_flag_bitmask("POWER", Powers(thing));
    Warnings(clone) = Warnings(thing);
    if (Wizard(clone) || Royalty(clone) || Warnings(clone) ||
        !null_flagmask("POWER", Powers(clone)))
      notify(player,
             T
             ("Warning: @CLONE/PRESERVE on an object with WIZ, ROY, @powers, or @warnings."));
  }
  /* We give the clone the same modification time that its
   * other clone has, but update the creation time */
  ModTime(clone) = ModTime(thing);
  CreTime(clone) = mudtime;
  Type(clone) = Type(thing);

  Contents(clone) = Location(clone) = Next(clone) = NOTHING;
  if (IsRoom(thing))
    Exits(clone) = NOTHING;
  else
    Home(clone) = Home(thing);
  atr_cpy(clone, thing);

  queue_event(player, "OBJECT`CREATE", "%s,%s",
              unparse_objid(clone), unparse_objid(thing));
  return clone;

}
Пример #3
0
    void CHSInterface::UnsetToggle(int objnum, int flag)
#endif
{
#ifdef PENNMUSH
    clear_flag_internal(objnum, flag);
#endif

#ifdef TM3
    s_Flags3(objnum, Flags3(objnum) & ~flag);
#endif

#ifdef MUX
    s_Flags(objnum, FLAG_WORD3, Flags3(objnum) & ~flag);
#endif
}
Пример #4
0
/** Clone an object.
 * \verbatim
 * This is the top-level function for @clone, which creates a duplicate
 * of a (non-player) object.
 * \endverbatim
 * \param player the enactor.
 * \param name the name of the object to clone.
 * \param newname the name to give the duplicate.
 * \param preserve if 1, preserve ownership and privileges on duplicate.
 * \paran newdbref the (unparsed) dbref to give the object, or NULL to use the next free
 * \return dbref of the duplicate, or NOTHING.
 */
dbref
do_clone(dbref player, char *name, char *newname, int preserve, char *newdbref)
{
  dbref clone, thing;
  char dbnum[BUFFER_LEN];

  thing = noisy_match_result(player, name, NOTYPE, MAT_EVERYTHING);
  if ((thing == NOTHING))
    return NOTHING;

  if (newname && *newname && !ok_name(newname, IsExit(thing))) {
    notify(player, T("That is not a reasonable name."));
    return NOTHING;
  }

  if (!controls(player, thing) || IsPlayer(thing) ||
      (IsRoom(thing) && !command_check_byname(player, "@dig")) ||
      (IsExit(thing) && !command_check_byname(player, "@open")) ||
      (IsThing(thing) && !command_check_byname(player, "@create"))) {
    notify(player, T("Permission denied."));
    return NOTHING;
  }
  /* don't allow cloning of destructed things */
  if (IsGarbage(thing)) {
    notify(player, T("There's nothing left of it to clone!"));
    return NOTHING;
  }
  if (preserve && !Wizard(player)) {
    notify(player, T("You cannot @CLONE/PRESERVE. Use normal @CLONE instead."));
    return NOTHING;
  }

  if (!make_first_free_wrapper(player, newdbref)) {
    return NOTHING;
  }

  /* make sure owner can afford it */
  switch (Typeof(thing)) {
  case TYPE_THING:
    if (can_pay_fees(player, Pennies(thing))) {
      clone = clone_object(player, thing, newname, preserve);
      notify_format(player, T("Cloned: Object %s."), unparse_dbref(clone));
      if (IsRoom(player))
        moveto(clone, player, player, "cloned");
      else
        moveto(clone, Location(player), player, "cloned");
      current_state.things++;
      local_data_clone(clone, thing);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  global_eval_context.wenv, 0);
      return clone;
    }
    return NOTHING;
    break;
  case TYPE_ROOM:
    if (can_pay_fees(player, ROOM_COST)) {
      clone = clone_object(player, thing, newname, preserve);
      Exits(clone) = NOTHING;
      notify_format(player, T("Cloned: Room #%d."), clone);
      current_state.rooms++;
      local_data_clone(clone, thing);
      real_did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING,
                  global_eval_context.wenv, 0);
      return clone;
    }
    return NOTHING;
    break;
  case TYPE_EXIT:
    /* For exits, we don't want people to be able to link it to
       a location they can't with @open. So, all this stuff.
     */
    switch (Location(thing)) {
    case NOTHING:
      strcpy(dbnum, "#-1");
      break;
    case HOME:
      strcpy(dbnum, "home");
      break;
    case AMBIGUOUS:
      strcpy(dbnum, "variable");
      break;
    default:
      strcpy(dbnum, unparse_dbref(Location(thing)));
    }
    if (newname && *newname)
      clone = do_real_open(player, newname, dbnum, NOTHING);
    else
      clone = do_real_open(player, Name(thing), dbnum, NOTHING);
    if (!GoodObject(clone)) {
      return NOTHING;
    } else {
      atr_cpy(clone, thing);
      clone_locks(player, thing, clone);
      Zone(clone) = Zone(thing);
      Parent(clone) = Parent(thing);
      Flags(clone) = clone_flag_bitmask("FLAG", Flags(thing));
      if (!preserve) {
        clear_flag_internal(clone, "WIZARD");
        clear_flag_internal(clone, "ROYALTY");
        Warnings(clone) = 0;    /* zap warnings */
        Powers(clone) = new_flag_bitmask("POWER");      /* zap powers */
      } else {
        Warnings(clone) = Warnings(thing);
        Powers(clone) = clone_flag_bitmask("POWER", Powers(thing));
      }
      if (Wizard(clone) || Royalty(clone) || Warnings(clone) ||
          !null_flagmask("POWER", Powers(clone)))
        notify(player,
               T
               ("Warning: @CLONE/PRESERVE on an object with WIZ, ROY, @powers, or @warnings."));
      notify_format(player, T("Cloned: Exit #%d."), clone);
      local_data_clone(clone, thing);
      return clone;
    }
  }
  return NOTHING;

}
Пример #5
0
/** Change an object's zone.
 * \verbatim
 * This implements @chzone.
 * \endverbatim
 * \param player the enactor.
 * \param name name of the object to change zone of.
 * \param newobj name of new ZMO.
 * \param noisy if 1, notify player about success and failure.
 * \param preserve was the /preserve switch given?
 * \param pe_info the pe_info for lock and permission checks
 * \retval 0 failed to change zone.
 * \retval 1 successfully changed zone.
 */
int
do_chzone(dbref player, char const *name, char const *newobj, bool noisy,
          bool preserve, NEW_PE_INFO *pe_info)
{
  dbref thing;
  dbref zone;
  int has_lock;

  if ((thing = noisy_match_result(player, name, NOTYPE, MAT_NEARBY)) == NOTHING)
    return 0;

  if (!newobj || !*newobj || !strcasecmp(newobj, "none"))
    zone = NOTHING;
  else {
    if ((zone = noisy_match_result(player, newobj, NOTYPE, MAT_EVERYTHING))
        == NOTHING)
      return 0;
  }

  if (Zone(thing) == zone) {
    if (noisy)
      notify(player, T("That object is already in that zone."));
    return 0;
  }


  if (!controls(player, thing)) {
    if (noisy)
      notify(player, T("You don't have the power to shift reality."));
    return 0;
  }
  /* a player may change an object's zone to:
   * 1.  NOTHING
   * 2.  an object he controls
   * 3.  an object with a chzone-lock that the player passes.
   * Note that an object with no chzone-lock isn't valid
   */
  has_lock = (getlock(zone, Chzone_Lock) != TRUE_BOOLEXP);
  if (!(Wizard(player) || (zone == NOTHING) || controls(player, zone) ||
        (has_lock && eval_lock_with(player, zone, Chzone_Lock, pe_info)))) {
    if (noisy) {
      if (has_lock) {
        fail_lock(player, zone, Chzone_Lock,
                  T("You cannot move that object to that zone."), NOTHING);
      } else {
        notify(player, T("You cannot move that object to that zone."));
      }
    }
    return 0;
  }
  /* Don't chzone object to itself for mortals! */
  if ((zone == thing) && !Hasprivs(player)) {
    if (noisy)
      notify(player, T("You shouldn't zone objects to themselves!"));
    return 0;
  }
  /* Don't allow circular zones */
  if (GoodObject(zone)) {
    dbref tmp;
    int zone_depth = MAX_ZONES;
    for (tmp = Zone(zone); GoodObject(tmp); tmp = Zone(tmp)) {
      if (tmp == thing) {
        notify(player, T("You can't make circular zones!"));
        return 0;
      }
      if (tmp == Zone(tmp))     /* Ran into an object zoned to itself */
        break;
      zone_depth--;
      if (!zone_depth) {
        notify(player, T("Overly deep zone chain."));
        return 0;
      }
    }
  }

  /* Don't allow chzone to objects without elocks!
   * If no lock is set, set a default lock (warn if zmo are used for control)
   * This checks for many trivial elocks (canuse/1, where &canuse=1)
   */
  if (zone != NOTHING)
    check_zone_lock(player, zone, noisy);

  /* Warn Wiz/Royals when they zone their stuff */
  if ((zone != NOTHING) && Hasprivs(Owner(thing))) {
    if (noisy)
      notify(player, T("Warning: @chzoning admin-owned object!"));
  }
  /* everything is okay, do the change */
  Zone(thing) = zone;

  /* If we're not unzoning, and we're working with a non-player object,
   * we'll remove wizard, royalty, inherit, and powers, for security, unless
   * a wizard is changing the zone and explicitly says not to.
   */
  if (!Wizard(player))
    preserve = 0;
  if (!preserve && ((zone != NOTHING) && !IsPlayer(thing))) {
    /* if the object is a player, resetting these flags is rather
     * inconvenient -- although this may pose a bit of a security
     * risk. Be careful when @chzone'ing wizard or royal players.
     */
    clear_flag_internal(thing, "WIZARD");
    clear_flag_internal(thing, "ROYALTY");
    clear_flag_internal(thing, "TRUST");
    destroy_flag_bitmask("POWER", Powers(thing));
    Powers(thing) = new_flag_bitmask("POWER");
  } else {
    if (noisy && (zone != NOTHING)) {
      if (Hasprivs(thing))
        notify(player, T("Warning: @chzoning a privileged player."));
      if (Inherit(thing))
        notify(player, T("Warning: @chzoning a TRUST player."));
    }
  }
  if (noisy)
    notify(player, T("Zone changed."));
  return 1;
}