RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Using OnItemLifted to set decay = true

Alcsaar

Sorceror
I've been trying to figure out how to do this for some reason now.

In the script for one of my rares, I have this:

Code:
 public override bool Decays{  get{ return false; } }
        
        public override void OnItemLifted( Mobile from, Item item )
        {
            public override bool Decays{  get{ return true; } }
        }

It should be obvious what I'm trying to do here, when the item is created I want it to not decay. that works fine - but I want it to become decayable once it has been picked up. However, the second I try to add the second part of the script, the onitemlifted part, I get errors. If I remove the
Code:
            public override bool Decays{  get{ return true; } }

Part from the OnItemLifted, it compiles fine, but obviously its not doing anything then.

So my question is, how do I over ride the decays property of an item in the script once it has been picked up?
 

Alcsaar

Sorceror
Edit button is broken for me, so I'll just reply. After digging through google searches since I can't seem to get runuo's search button to work, it seems like some one else tried that exact same thing and it won't work. Apparently you are unable to call bool decays from inside another call.
 

ViWinfii

Sorceror
Hey just so you know, you may not need to worry about when it decays. Decay is defined like this in Item.cs:

Code:
[CommandProperty(AccessLevel.Decorator)]
        public virtual bool Decays
        {
            get
            {
                return (Movable && Visible);
            }
        }

So when it is picked up out of a chest or looted, it becomes visible and Decays becomes true. Assuming of course it is already Movable.
 

Alcsaar

Sorceror
Hey just so you know, you may not need to worry about when it decays. Decay is defined like this in Item.cs:

Code:
[CommandProperty(AccessLevel.Decorator)]
        public virtual bool Decays
        {
            get
            {
                return (Movable && Visible);
            }
        }

So when it is picked up out of a chest or looted, it becomes visible and Decays becomes true. Assuming of course it is already Movable.

Not sure what you mean. Its fine for things like rares that spawn in containers, but a lot of rares spawn in the over world (Buc's Den Rocks, Yew Fruit Basket, dozens others). Those decay 1 hour after spawning.
 

zerodowned

Sorceror
If you want an item to self delete after the player picks it up and puts it in their pack, that's a self delete timer.
Decay means if a player puts something on the ground and it stays there, and is not picked up again until the world decay timer ends, then it will be deleted.

there's plenty of examples of self delete timers out there but if you want the item to be equipable, then i suggest looking at http://www.runuo.com/community/thre...-timer-timer-in-attributes-list.515499/page-2

you won't need to full script, but if i remember correctly, there can be an issue with the item deleting while a player is logged out. or maybe it was just sending a message to the player if they're logged out, as my original script for the half life bow included a message that sent to the player when it self deleted.
 

Alcsaar

Sorceror
If you want an item to self delete after the player picks it up and puts it in their pack, that's a self delete timer.
Decay means if a player puts something on the ground and it stays there, and is not picked up again until the world decay timer ends, then it will be deleted.

there's plenty of examples of self delete timers out there but if you want the item to be equipable, then i suggest looking at http://www.runuo.com/community/thre...-timer-timer-in-attributes-list.515499/page-2

you won't need to full script, but if i remember correctly, there can be an issue with the item deleting while a player is logged out. or maybe it was just sending a message to the player if they're logged out, as my original script for the half life bow included a message that sent to the player when it self deleted.

I must not be clear enough in my posts or something, there always seems to be a lot of people not understanding what I'm asking for...

I don't want the item to self delete when picked up, on a timer or not. I have "daily rares" spawning (like they do on OSI). The problem is, on OSI the respawn timer is 100% ALWAYS after the server comes back up, so the item decaying is never an issue because you know exactly when it spawns.

When you are trying to replicate this using spawners on RunUO servers, the spawn time is NEVER guaranteed. I want players to have the chance to actually get the rares before they decay like normal, so I'm trying to find ways to stop them from decaying after they initially spawn, UNTIL a player interacts with them. Once a player grabs one I want them to have the 1hr decay timer as per normal. That way if a house with rares falls the rares don't sit there forever not decaying.
 

pooka01

Sorceror
Code:
private m_Lifted = false;
 
public override bool Decays{get{ return (m_Lifted) ? return base.Decays : false;}}
 
public override idk OnDragLift(whatever goes here)
{
if (!m_Lifted)
  m_Lifted = true;
}
something like that, still unsure about the decay part tho.
 

pooka01

Sorceror
true, you could add the rares gatherable with thestealing skill (even with 0 stealing), such as: if (target is SpawnedRare) or whatever base template it is.
 

Alcsaar

Sorceror
true, you could add the rares gatherable with thestealing skill (even with 0 stealing), such as: if (target is SpawnedRare) or whatever base template it is.

This introduces its own problems. For example, if I wanted to add another set I could simply make a OnSingleClick over ride that makes the item movable. That worked, but people who have gathered daily rares before know it shouldn't be necessary and often it might make people think a rare isn't spawned.

There is also another serious bug. If the item is locked down in a house, its actually flagged as movable = false. So anyone who clicks on a rare locked down in a house can simply pick it up and take it. I don't know how to avoid this because there is no property or flag for when an item is locked down, its just set to movable false.
 

Alcsaar

Sorceror
Pooka I tried to use the code you suggested but I'm getting invalid expression and invalid token errors in IDE.

Heres the code i cobbled together.

Code:
      private m_Lifted = false;
 
        public override bool Decays{get{ return (m_Lifted) ? return base.Decays : false;}}
 
        public override void OnDragLift( Mobile from, Item item )
            {
                if (!m_Lifted)
                m_Lifted = true;
            }

Its giving on error for the m_Lifted = false; line and the override bool decays line.

Edit* Tinkered around with it a bit and got it working (for example, private m_Lifted = false; needed to be private bool m_Lifted = false;)

However, it doesn't matter. Because the item is set to not decay/cant move it, the ondraglift method is never called because you can't lift the object.

The only solution I can see that might work is if there is a method that detects a player nearby that sets it to movable.
 

Alcsaar

Sorceror
I have it working using OnMovement method. Its initially set to movable false and when a player enters with in 5 tiles it becomes movable true. HOWEVER, this is going to cause issues with house lockdowns. If its locked down in a house and a player moves near it its going to set it to movable true again and anyone can simply pick it up from a house, so I need the code to check and see and make sure its not in a house region first.

Here is what I have so far:

Code:
      private int m_Range = 5;
        public override bool HandlesOnMovement { get { return true; } }
 
        public override void OnMovement(Mobile m, Point3D oldLocation)
        {
            if (m.Player && m.InRange(this, m_Range))
            {
                Movable = true;
            }
        }

This works fine, now I justr need to find out the proper syntax to add to the if statement to make sure the item isn't in a house region. Any help?
 

pooka01

Sorceror
Add a check, if you lift it, makes it m_Lifted, then check in the handle movement if it has already been lifted.

Code:
 private bool m_Lifted = false;
 private int m_Range = 5;
 
 public override bool HandlesOnMovement { get { return true; } }
 
 public override void OnMovement(Mobile m, Point3D oldLocation)
 {
  if (!m_Lifted && m.Player && m.InRange(this, m_Range))
  {
   Movable = true;
  }
 }
 public override void OnDragLift( Mobile from, Item item )
 {
  if (!m_Lifted)
   m_Lifted = true;
 }
This basically.
If someone walks next to it, it gets movable, then the decay starts, so he will have to take it or it decays 1 hour after.
Sounds fair enough? or you want something that goes back to movable false when nobody is around?
 

Alcsaar

Sorceror
Add a check, if you lift it, makes it m_Lifted, then check in the handle movement if it has already been lifted.

Code:
private bool m_Lifted = false;
private int m_Range = 5;
 
public override bool HandlesOnMovement { get { return true; } }
 
public override void OnMovement(Mobile m, Point3D oldLocation)
{
  if (!m_Lifted && m.Player && m.InRange(this, m_Range))
  {
  Movable = true;
  }
}
public override void OnDragLift( Mobile from, Item item )
{
  if (!m_Lifted)
  m_Lifted = true;
}
This basically.
If someone walks next to it, it gets movable, then the decay starts, so he will have to take it or it decays 1 hour after.
Sounds fair enough? or you want something that goes back to movable false when nobody is around?

Thank god some one is here! I'm so close to getting this to work!

I would prefer it to remain movable=true even if no one is around. If a player walks into range of a rare and doesn't pick it up, all well.

However, the major issue with this method is moving next to a rare that is locked down in a house will set it to movable=true, so im trying to do a check to make sure the item isn't in a house region.

I got it working that if the player is in a house region it won't work, but if i have the item locked down on the patio of a house and a player outside walks near it, its set to movable true again. But using this method doesn't work if you try to use the item's region. For example here is the code that checks if the player is in a house region:

Code:
        private int m_Range = 5;
        public override bool HandlesOnMovement { get { return true; } }
 
        public override void OnMovement(Mobile m, Point3D oldLocation)
 
        {
            Region r = m.Region;
            if (m.Player && m.InRange(this, m_Range) && !r.IsPartOf( typeof( Server.Regions.HouseRegion )))
            {
                Movable = true;
            }
        }

This code succesfully checks to make sure the player isn't in a house region. I need it to check if the ITEM is in a house region instead, not the player. As it is possible for the player to be outside of the house region.

P.S. unless im missing something you don't need the onlift method if you use range detection method, you just set it to movable true when the player walks into range.
 

pooka01

Sorceror
morphitem.cs

Code:
public override bool HandlesOnMovement{ get{ return true; } }
  public override void OnMovement( Mobile m, Point3D oldLocation )
  {
   if ( Utility.InRange( m.Location, Location, CurrentRange ) || Utility.InRange( oldLocation, Location, CurrentRange ) )
    Refresh();
  }
  public override void OnMapChange()
  {
   if ( !Deleted )
    Refresh();
  }
  public override void OnLocationChange( Point3D oldLoc )
  {
   if ( !Deleted )
    Refresh();
  }
  public void Refresh()
  {
   bool found = false;
   foreach ( Mobile mob in GetMobilesInRange( CurrentRange ) )
   {
    if ( mob.Hidden && mob.AccessLevel > AccessLevel.Player )
     continue;
    found = true;
    break;
   }
   if ( found )
    ItemID = ActiveItemID;
   else
    ItemID = InactiveItemID;
   Visible = ( ItemID != 0x1 );
  }

windchimes.cs
Code:
  public bool IsOwner( Mobile mob )
  {
   BaseHouse house = BaseHouse.FindHouseAt( this );
   return ( house != null && house.IsOwner( mob ) );
  }

you can play with those to get the in/out range, to reset it to movable false, then use the BaseHouse.FindHouseAt( this ) to check if it is in a house.
 

Alcsaar

Sorceror
Yea I've been trying to play around with this, im getting compile errors when using BaseHouse house = BaseHouse.FindHouseAt( this ); "Type or namespace "BaseHouse" could not be found, does not exist in the current context". Obviously I'm missing a step. I don't know what the Public bool is owner thing is used for, i don't think i need that here.

Edit* DOH!

Forgot to add Using.Multis to the top of the script. If there is a way to avoid doing this, please let me know. I'm trying to only have to add one block of code to each rare item.

Regardless this seems to be working as intended. If the item isn't locked down, it will set movable=true when a player walks into range. If it IS locked down, it wont.

Here is the code that I used to get it working.
Code:
        private int m_Range = 4;
        public override bool HandlesOnMovement { get { return true; } }
 
        public override void OnMovement(Mobile m, Point3D oldLocation)
 
        {
            BaseHouse house = BaseHouse.FindHouseAt(this);
            Region r = m.Region;
            if (m.Player && m.InRange(this, m_Range))
            {
                if ( !house.IsLockedDown(this))
                {
                    Movable = true;
                }
            }
        }

Then at the top of the script you just need to make sure to add using Server.Multis; under using System;


If anyone sees potential issues with how I did this please enlighten me. It was a messy project and I'm sure something could have been done better. (I'm still learning)
 
Top