ID:272952
 
1. Does MouseEntered() detect when it has "entered" a button element? If so, could I get a little example?
Nevermind. http://www.byond.com/developer/forum/?id=705761 that post has answered my question :P

2. Are you able to change a client's macros, through the game's programming, during runtime? If so, an example for that would be nice, though I think I have something in mind right now.

E.g. I drag a skill to a skillbar slot, and the macro to that specific slot changes to the verb that's used to "cast" the skill.

3. I would very much like to do a pet system for my game, but I've run into a roadblock: saving the pet. I want it so when a player logs out, their pet is saved somehow, so that upon logging in again. their pet will appear again. I do not want to have to move the pet to the player's inventory just to save it along with the player. I hope that makes sense. How would I go about accomplishing this?
Spunky_Girl wrote:
2. Are you able to change a client's macros, through the game's programming, during runtime? If so, an example for that would be nice, though I think I have something in mind right now.

E.g. I drag a skill to a skillbar slot, and the macro to that specific slot changes to the verb that's used to "cast" the skill.

Just use one verb that calls the appropriate proc.

3. I would very much like to do a pet system for my game, but I've run into a roadblock: saving the pet. I want it so when a player logs out, their pet is saved somehow, so that upon logging in again. their pet will appear again. I do not want to have to move the pet to the player's inventory just to save it along with the player. I hope that makes sense. How would I go about accomplishing this?

If you save the player, and the player has a reference to the pet, the pet will be saved as well. All you need to do is make sure it Write() and Read()s correctly (ie: saving the x,y,z, or alternatively just in the player's Read() relocate the pet to be next to the player). There's no need to save the pet explicitly.
In response to Garthor
Garthor wrote:
Spunky_Girl wrote:
2. Are you able to change a client's macros, through the game's programming, during runtime? If so, an example for that would be nice, though I think I have something in mind right now.

E.g. I drag a skill to a skillbar slot, and the macro to that specific slot changes to the verb that's used to "cast" the skill.

Just use one verb that calls the appropriate proc.

I think I getcha. I'm not 100% sure though.

3. I would very much like to do a pet system for my game, but I've run into a roadblock: saving the pet. I want it so when a player logs out, their pet is saved somehow, so that upon logging in again. their pet will appear again. I do not want to have to move the pet to the player's inventory just to save it along with the player. I hope that makes sense. How would I go about accomplishing this?

If you save the player, and the player has a reference to the pet, the pet will be saved as well. All you need to do is make sure it Write() and Read()s correctly (ie: saving the x,y,z, or alternatively just in the player's Read() relocate the pet to be next to the player). There's no need to save the pet explicitly.

So if I have a variable...
mob/player/var/myPet

...and set it equal to the tamed pet. All I would have to do upon that player logging in is create a new pet mob, and set it equal to the player's variable?
Spunky_Girl wrote:
3. I would very much like to do a pet system for my game, but I've run into a roadblock: saving the pet. I want it so when a player logs out, their pet is saved somehow, so that upon logging in again. their pet will appear again. I do not want to have to move the pet to the player's inventory just to save it along with the player. I hope that makes sense. How would I go about accomplishing this?

Why not? I've found that one of the easiest ways to save a pet is just to stash it in their contents when they leave, then locate() it on login and drop it on the map. Since the pet is in src.contents on Login(), you have a convenient reference to the owner's mob and can just refresh the pet mob's data. With the proper variables marked as tmp, I don't see why that can't also be an option.
In response to Mobius Evalon
I'm not sure why, but I get a runtime error whenver I stash the pet mob in the player's contents. Something about it being a "bad mob" or whatever.
That's all well and dandy, but the way I want it to be is by drag and drop onto a button element. And then I was thinking upon MouseDrop(), the button's command could change to the verb that the dragged skill has. I use objs for my skills, by the way.
Spunky_Girl wrote:
2. Are you able to change a client's macros, through the game's programming, during runtime?

Yes, you can change interface-added macros' command and such with winset(). You can either give the macros IDs and use that to refer to them, or you can use their key combination instead - read on them in the Skin Reference for more info.
So yes, you can change a macro to execute a different command when needed in order to do what you want. Another method is what Garthor suggested: have the macro always execute the same command, which fires up a verb which then decides what action it should take and calls the appropriate proc. e.g., if you store a player's skill in a specific var, you might have a macro that executes a verb like this:
skill
proc/Use(mob/player/P)

mob/player
var/list/skill_slots
verb/UseSkillSlot(n as num)
set hidden = 1
if(src.skill_slots)
var/skill/S = src.skill_slots[n] //get the skill at that slot
if(S) S.Use(src) //self-explanatory

This way the command the macro refers to (e.g. UseSkillSlot 1) is static, only the player's appropriate var changes. This var would also be conveniently saved with the player's mob and you wouldn't need to re-edit players' macros when they login (though you'd probably need to do other initializations with the HUD either way!). So this method might be a little safer/better sometimes, but you could use either method.

3. I would very much like to do a pet system for my game, but I've run into a roadblock: saving the pet.

As others have said, all you need to do is make the mob have a direct reference to the pet (in a var that isn't marked 'tmp'), and it'll save automatically with it. It isn't necessary for that reference to be in contents, you can use any var, such as a custom pet var with a reference or a pets list which references the pets. As with player saving, the location of movables isn't automatically saved, so you'll need to do that manually (you may even be able to use the existing code handling mobs for that and share it with the pets).
In response to Spunky_Girl
Spunky_Girl wrote:
So if I have a variable...
> mob/player/var/myPet
>

...and set it equal to the tamed pet. All I would have to do upon that player logging in is create a new pet mob, and set it equal to the player's variable?

No. If you have a variable set to the pet, you would do absolutely nothing, and the pet would be saved and loaded. The only thing you would need to likely do is place the pet on the map somewhere, because its location is not going to get saved if it's on a turf. You would do this in either the mob/pet/Read() and Write(), or the mob/player/Read() and Write().
Tko37 wrote:
As for number 3... I don't think saving the whole pet is neccesary or beneficial to the..size of your savefile. I don't know much about Byond though so :D Goodluck

Unless you do something dumb like change the icon, saving an object is not going to be making gigantic savefiles. Saving a "pet" is going to be fundamentally the same as saving any other object with a player, such as items in their contents.

Changing the icon results in the entire icon being stored in the savefile, however, which CAN quickly bloat it. There are ways around this, but they boil down to "if you changed the icon, then save data required to get that icon back, rather than saving the whole icon."
In response to Garthor
Garthor wrote:
No. If you have a variable set to the pet, you would do absolutely nothing, and the pet would be saved and loaded. The only thing you would need to likely do is place the pet on the map somewhere, because its location is not going to get saved if it's on a turf. You would do this in either the mob/pet/Read() and Write(), or the mob/player/Read() and Write().

Deleting the pet mob upon the player logging out will not affect that at all?
In response to Spunky_Girl
Won't affect the savefile, it's already written.
In response to Spunky_Girl
As long as you save the player (and so the pet with it) before you delete the pet, no.
In response to Garthor
Awesome! ^-^ I'll definitely try this stuff out.

Right now, though, I'm having troubles with the mouse_drag_pointer variable in my MouseDrag() proc, and the image paramter for a button element (which when you think about it, it's the same problem, but with two different things).

obj/skills/MouseDrag()
mouse_drag_pointer = ???

obj/skills/MouseDrop(over_object,src_location,over_location,src_control="info1",over_control,params)
if(over_controll == "default.one")
winset(usr,"default.one","image=???")


I've tried doing...
var/html = "<IMG SRC=\ref[src.icon] ICONSTATE='[src.icon_state]'>"
winset(usr,"default.one","image=[html]")

and...

winset(usr,"default.one","image=[src.icon]")

and...

var/i = icon(src.icon,src.icon_state)
winset(usr,"default.one","image=[i]")

...but niether of them worked for either case. Is there something special I have to do, to get the button and mouse_drag_pointer to display the proper icon, and icon_state?
In response to Spunky_Girl
Spunky_Girl wrote:
Right now, though, I'm having troubles with the mouse_drag_pointer variable in my MouseDrag() proc,

What kind of problem? From the "???", I guess you don't know what to set it to? First, you shouldn't even do it in MouseDrag(), you're setting a var of src to a constant value - this only needs to be done once, initialized after the object is created - instead of every time it's dragged over something.
As for not knowing what to set it to, look it up. From what I remember, that var supports a whole range of value types, it can take an object reference, text string (icon_state) and stuff, it works similarly to adding overlays; it uses a static snapshot of the current appearance of whatever you've used. If you wanted the object to simply be dragged with its own icon, you could just set the var to src or src.icon_state (both give an almost identical result).

and the image paramter for a button element
var/html = ""

I'd guess that doesn't work because HTML is unsupported there, not a surprise, since it's supposed to be set to an image, not some text/HTML. That might've worked in the button's text if that supports HTML.

winset(usr,"default.one","image=[src.icon]")
var/i = icon(src.icon,src.icon_state)
winset(usr,"default.one","image=[i]")

These won't work because, remember, you're setting the value in text string format - and values change when they're embedded in a text string:
"[icon file]" can give you an empty string if it's a dynamic icon with no filename, so it's no good. I think it should work with a 'normal' icon file, though.
"[/icon object]" just gives the text string containing that object's type, which is always "/icon", so it's useless and doesn't refer to any icon at all.
What you CAN use however to give a valid text reference to an icon is the \ref text macro. Look it up in the Reference and read this post for more info: [link]
2 I have seen skill bars in games, that popular naruto game has one, not sure how to do it though, you might want to shoot an email to the guy, see if he will help you. I never had use for it. I have also seen a macro sheet, which is usually used for fighting in some source codes. I believe it is the script file.

3. Pet system...

You could have a pet summon verb, where you can recall the bet to your location as well as save the pet's variables to the owner's and upon summoning the verb, the pet will recive the values of the variables. For examble.


mob
var
health = 100
maxhealth = 100
pethealth = 50
petmaxhealth=50



verb
petsummon()
var/mob/pet/M
M.health = pethealth
M.maxhealth = petmaxhealth


something like that. i cant write out the whole code without your source code infront of me, im not a guru like that, but try it. just save the pet's variables to the player.
In response to Kaioken
Thanks a lot Kaioken! :D One final problem, however (ugh, right? T.T).

I'm using your example for the skill bar thing, where you have a skill_slots list var.

obj/skill
New()
..()
mouse_drag_pointer = src.icon_state
proc/Use(mob/player/p)
if(hascall(src,"activate"))
call(src,"activate")(p)

obj/skill/MouseDrop(over_object,src_location,over_location,src_control="info1",over_control,params)
var/mob/player/p = usr
if(over_control == "default.one")
var/icon/i = icon(src.icon,src.icon_state)
winset(p,"default.one","image='["\ref[i.icon]"]';command='Skill-Bar 1'")
if(!p.skill_slots) p.skill_slots = new
p.skill_slots[1] = src
p<<winget(usr,"default.one","command")

mob/player
var/list/skill_slots
verb/Skill_Bar(n as num)
set hidden = 1
if(src.skill_slots)
var/obj/skill/s = src.skill_slots[n]
if(s) s.Use(src)


When MouseDrop() is called, it gives me a "index out of bounds error" error and says that it's the p.skill_slots[1] = src line that's giving me the error.
In response to Spunky_Girl
Spunky_Girl wrote:
I'm using your example for the skill bar thing, where you have a skill_slots list var.

Okay, but when doing such a thing, make sure to understand how the code works and read it a couple of times first, then adapt it into your game. That wasn't a complete or functional example, only an illustrative one.

First, there are a couple of quirks in your code:
  • >   proc/Use(mob/player/p)
    > if(hascall(src,"activate"))
    > call(src,"activate")(p)

    What are those hascall() and call() for? It should be certain that the skill object has that proc if it was declared on it, and it's also pointless to non-dynamically call [always the same] proc through call(). You might as well get rid of Use() entirely and just call your activate() directly.
  • MouseDrop(over_object,src_location,over_location,src_control="info1",over_control,params)
    What's the bolded part for, too? I'm not sure what you think it does, but that syntax is for setting a default value to an argument (which it is set to if no value was given), and I don't see that part doing anything useful.
  • winset(p,"default.one","image='["\ref[i.icon]"]';command='Skill-Bar 1'")
    Wouldn't setting the command once in the interface editor be enough? It looks like you shouldn't have to do that repeatedly.


When MouseDrop() is called, it gives me a "index out of bounds error" error and says that it's the p.skill_slots[1] = src line that's giving me the error.
>       if(!p.skill_slots) p.skill_slots = new
> p.skill_slots[1] = src


Have a look in your code, it's easy to find the error. The error message is self-explanatory: you get it when you try to access an element of a list with an out-of-bounds index (meaning it's either bigger than the amount of items in the list, or smaller than 1, which is the first item). Here, you're always creating the list empty, but you're trying to access its first element immediately afterward - but there is none, as the list is empty - hence the error.
What my example was supposed to work like, is to have the skill_slots list initialized with a number of (empty, or in other words null, when the respective slot is unused) elements corresponding to the number of skill slots available. So if you have 3 skill slots, you initialize the list with 3 elements, then you can index into them directly without worrying about getting out of bounds. You can initialize a list like so through a number of methods, all of these produce the same end result:
L = new /list(3)

L = list(null,null,null)

var/list/L = new
L.Add(null,null,null)

(As you can probably imagine, the first one would be kinda preferred)
Also note you can initialize a list to a number of elements when declaring its var, through a special syntax - this also defines that var as a /list type automatically:
var/L[3]

The above is equivalent to:
var/list/L = new(3)

You should generally try not to initialize lists until they're needed however (and 'uninitialize' them when they're no longer needed), so this declaration syntax is more suitable for a list that is always immediately needed, which the skill_slots one probably isn't.

Lastly, about this part:
    if(over_control == "default.one")
var/icon/i = icon(src.icon,src.icon_state)
winset(p,"default.one","image='["\ref[i.icon]"]';command='Skill-Bar 1'")
if(!p.skill_slots) p.skill_slots = new
p.skill_slots[1] = src
p<<winget(usr,"default.one","command")

Naturally, that only works for one label, default.one. Going about it in this way, you'll need to duplicate this code for every label, or at least do that in a loop by having all the label IDs in a list and comparing to each one. You should consider a better method to do this dynamically for all the labels. Here's an idea that sprang to mind: you could have all of the labels named in a certain convention according to their slot, with a constant prefix - for example SkillSlot1, SkillSlot2, etc. Then, you could check if the over_control string begins with SkillSlot to know if the obj was dropped on one of those labels, and if so, copy the character after the prefix part, convert it to a number, [check if it's valid,] then use that to index into the list and the correct slot dynamically. Boom, all your labels are now taken care of automatically without writing code for each one.
To do the above, you'd need to use some findtext() and copytext(), of course. You could use only the latter, but it's better to use the former when you can (like here, for checking if the string begins with the prefix) because it's more efficient. Also, remember that similarly to lists, you can go out of bounds with strings as well - f.ex. copytext(Txt,5,6) will give you an error is Txt is less than 5 characters long.
In response to Kaioken
How's this?

obj/jutsu/MouseDrop(over_object,src_location,over_location,src_control,over_control,params)
var/mob/player/p = usr
if(findText("[over_control]","skillslot"))
if(!p.skill_slots) p.skill_slots = new/list(8)
var/icon/i = icon(src.icon,src.icon_state)
winset(p,over_control,"image='["\ref[i.icon]"]'")
var/n = text2num(copytext(over_control,18))
p.skill_slots[n] = src

mob/player
var/tmp/list/skill_slots
verb/Skill_Bar(n as num)
set hidden = 1
if(src.skill_slots)
var/obj/jutsu/j = src.skill_slots[n]
if(j) j:activate(src) //i used the colon because I have different sub-roots, but all the skills have the same proc name
In response to Spunky_Girl
That's no excuse for the colon; /obj/Jutsu should have the activate proc, not its children.
In response to Jeff8500
So uhhh... how do you propose I set up different skills that have different programming that can be referenced the same even when they have different sub-roots?

/obj/skill/magic
proc/activate(mob/player/p)
p<<"You have used magic!"

/obj/skill/ranged
proc/activate(mob/player/p)
p<<"You have used ranged!"

/obj/skill/melee
proc/activate(mob/player/p)
p<<"You have used melee!"
Page: 1 2