ID:160996
![]() Jul 1 2008, 6:54 am
|
|
i need a code that summons a creature to fight for the summoner, follow the person that summoned it, and will disappear after a couple of mins
|
I'm sorry, but I'm assuming he's posting in the "DEVELOPTER HOW-TO", because he doesn't know HOW TO. So instead of providing a meaningless response to the man, why not direct him in the right direction? Check out Rifthaven's pet demo. It'll help you figure out what to do.
-Drew |
Let's separate your question to four parts:
1. How to summon a creature 2. How to make it follow its summoner 3. How to make it fight for its summoner 4. And finally, how to make it disappear after some time All of these topics are somehow connected, but addressing them separately makes the answer more simple. To summon a creature you can use new T(), which creates a new object of type T. In your case, it's a creature. I imagine you'd want to know who the summoned creature's summoner is, so let's give each creature a variable called <code>master</code> and assign it via datum.New(). You want this to go both ways, so let's give the summoner a variable called <code>creature</code> in addition. mob/summoner When the creature's master moves and his creature is unoccupied, the creature follows. This means the creature goes to the last spot the master was in. We can handle this via mob/summoner.Move(). mob/summoner/Move(new_loc,new_dir) Note that I've given the create a new var: <code>following</code>. This is a boolean variable (a variable that can only be true or false) that determines whether the creature should be following its master or not. Here is the code for it: mob/creature Now for combat. "fighting for the summoner" is a very abstract way of explaining what you want, so I'm afraid I can't go into details here. In general, when the creature should be fighting its <code>following</code> variable is set to 0 (or "false") and it attacks its master's enemies. When combat is over, its <code>following</code> variable is set to 1 (or "true") again. The last question is how to make the creature disappear. mob/creature This is very straightforward. When the creature is created, it spawn()s <code>time_alive</code> ticks, and then calls the Die() proc which removes all references to it so BYOND will soon delete it automatically (this is more efficient than calling the del() proc manually). But there is a flaw here: we can't postpone or hasten the creature's deletion. The solution is simple enough, but I am weary after writing this much. I'd appreciate if someone else addresses it, otherwise I'll consider updating this post later. |
Aaiske Drew wrote:
I'm sorry, but I'm assuming he's posting in the "DEVELOPTER HOW-TO", because he doesn't know HOW TO. So instead of providing a meaningless response to the man, why not direct him in the right direction? Except, it wasn't more meaningless than your response, considering he did not ask "how to", but simply did nothing more than request "a code" with his 1-sentence topic. Check out Rifthaven's pet demo. It'll help you figure out what to do. It could come in handy, but you should beware of the badly made parts and bad practices. I'd suggest also checking out other demos, like SuperAntx', which isn't much better but at least it doesn't have usr abuse and repeated looping. |
DivineO'peanut wrote:
> New(location,mob/summoner/master) Note that this isn't entirely needed; first, calling simply "..()" will automatically pass all the arguments to it, and additionally, passing the location specifically to the default New() isn't necessary - it will be located at it regardless - it is done before New() is even called. > mob/summoner/Move(new_loc,new_dir) You should only move the summoned creature if the summoner has actually made a movement, though, not just because he tried to move but remained in place; this is of course easily done by adding "." as another condition for the if() check. Additionally, there is no need to supply a 2nd argument in the Move() call there; actually, it could only cause selecting an inappropriate dir and omitting it would automatically select the appropriate one (as the player and summoned-creature are in different positions and moving to different locations, the directions they move at are different). But there is a flaw here: we can't postpone or hasten the creature's deletion. The solution is simple enough, but I am weary after writing this much. I'd appreciate if someone else addresses it, otherwise I'll consider updating this post later. I'm not sure what you mean by this, but when doing a "reference delete" with atom objects (and as such are prone to being messed with by all sorts of code), you should probably ensure it by a quick spawn() to delete the object after a tick or so (if it's handled by the garbage collector and deleted, your spawn() won't even run, of course). |
Note that this isn't entirely needed; first, calling simply "..()" will automatically pass all the arguments to it, and additionally, passing the location specifically to the default New() isn't necessary - it will be located at it regardless - it is done before New() is even called. I am aware of that, but I prefer it this way. It is cleaner and more understandable. You should only move the summoned creature if the summoner has actually made a movement, though, not just because he tried to move but remained in place; this is of course easily done by adding "." as another condition for the if()check. I disagree. If the summoner moves, the creature should move with him regardless of a change in his location. For example, if you're stuck in a cell and want you and your creature to face up you can do so, or if your creature can fly and you want to move him to your location you can do it this way. Additionally, there is no need to supply a 2nd argument in the Move() call there; actually, it could only cause selecting an inappropriate dir and omitting it would automatically select the appropriate one (as the player and summoned-creature are in different positions and moving to different locations, the directions they move at are different). The "appropriate direction" in this case is the summoner's direction. If the master moves east and the creature moves north, the creature should face the master and not north. I'm not sure what you mean by this, but when doing a "reference delete" with atom objects (and as such are prone to being messed with by all sorts of code), you should probably ensure it by a quick spawn() to delete the object after a tick or so (if it's handled by the garbage collector and deleted, your spawn() won't even run, of course). Huh? Which part have you been paying attention to? I've been spawn()ing for a whole five minutes! Edit: please don't take this personally, but I'm getting tired of you arguing against absolutely everything in my posts. If there's something minor such as an unneeded argument or minor design issue (from your point of view), do keep it to yourself, because as you know we are both incredibly stubborn and these small things easily turn into two pages of garbage. In turn, I'll try to do the same. |
DivineO'peanut wrote:
I disagree. If the summoner moves, the creature should move with him regardless of a change in his location. For example, if you're stuck in a cell and want you and your creature to face up you can do so, or if your creature can fly and you want to move him to your location you can do it this way. But that could more often just move the summoned creature unexpectedly and possibly make the player more stuck. If you want to provide more precise control, it should be done by a more convenient and suitable method, rather than the summoner's own movement. For the purpose of merely 'following', then it should only move if the owner moved. Following. Or that is my opinion, at least. The "appropriate direction" in this case is the summoner's direction. If the master moves east and the creature moves north, the creature should face the master and not north. Ah, I see. I simply didn't realize that was wanted, since you didn't make that clear through the comments or otherwise. My bad. Edit: please don't take this personally, but I'm getting tired of you arguing against absolutely everything in my posts. I'm not taking it personally, and neither should you. =) No fuss here. If there's something minor such as an unneeded argument or minor design issue (from your point of view), do keep it to yourself, because as you know we are both incredibly stubborn and these small things easily turn into two pages of garbage. In turn, I'll try to do the same. If something is minor and makes no difference, I won't argue about it, and will simply just point it out if you haven't for the sake of readers and the possibility you've missed it. However, if you feel something important is badly done, there is nothing bad in saying so and arguing. Arguments aren't necessarily garbage by nature. I'll explain what I meant: I'm not sure what you mean by this, but when doing a "reference delete" with atom objects (and as such are prone to being messed with by all sorts of code), you should probably ensure it by a quick spawn() to delete the object after a tick or so (if it's handled by the garbage collector and deleted, your spawn() won't even run, of course). I noticed there was a spawn() before the call, but I meant also adding a spawn() at the end of the proc that will ensure the object is deleted in the case the garbage collector missed it. True, this isn't necessary, but as I said I feel it not-completely-safe to use the garbage collector to delete atoms in a full featured game, as other features/code may intercept the atom freely (unlike with datums, which would be fairly rare) and reference it, therefore preventing its desired deletion. Maybe I'm wrong and this won't even work, but this seems a viable catch-all solution for me: proc/Die() I guess I see your point though, this may be too in-depth for the purpose of a simple newbie thread... but I've already typed it out. Sorry. |
But that could more often just move the summoned creature unexpectedly and possibly make the player more stuck. If you want to provide more precise control, it should be done by a more convenient and suitable method, rather than the summoner's own movement. For the purpose of merely 'following', then it should only move if the owner moved. Following.Or that is my opinion, at least. That's a good point, but that's not a reason why the creature won't be able to do that without any special controls. If you can make it easier on the players by allowing some flexibility, why not do so? I noticed there was a spawn() before the call, but I meant also adding a spawn() at the end of the proc that will ensure the object is deleted in the case the garbage collector missed it. True, this isn't necessary, but as I said I feel it not-completely-safe to use the garbage collector to delete atoms in a full featured game, as other features/code may intercept the atom freely (unlike with datums, which would be fairly rare) and reference it, therefore preventing its desired deletion. Maybe I'm wrong and this won't even work, but this seems a viable catch-all solution for me: Nothing is completely safe. If there are any references to this object, it is the programmer's job to remove them. I'm not entirely against using ensureDel() but it seems like a lazy solution, and kinda defeats the purpose of Die(), which is efficiency. If something is minor and makes no difference, I won't argue about it, and will simply just point it out if you haven't for the sake of readers and the possibility you've missed it. However, if you feel something important is badly done, there is nothing bad in saying so and arguing. Arguments aren't necessarily garbage by nature. Ha ha, so did I. Okay, that's a lie, I just have to defend my post which took me 30 minutes to write. Thank you for your understanding. :P |
DivineO'peanut wrote:
That's a good point, but that's not a reason why the creature won't be able to do that without any special controls. If you can make it easier on the players by allowing some flexibility, why not do so? Because what I've said in the part you've quoted. But no matter, I just needed to say what I think, it's okay if you disagree. Nothing is completely safe. Eh, not completely true (or valid as an argument). You can make things safer by being aware of possible issues and accounting for them, like I've suggested. To be safer, you could simply use del straightaway, but of course we want to avoid that as it is considerably less efficient by comparison. If there are any references to this object, it is the programmer's job to remove them. Indeed, but starting to hunt for references yourself throughout various programmed systems is a pain and inefficient and inflexible, not to mention completely defeats the purpose, because then you might as well just use 'del' straightaway, because the above is exactly what it does and why it's slower. But, it does it internally, and more robustly than your code can. I'm not entirely against using ensureDel() but it seems like a lazy solution, I'm going to have to disagree here. It's a quick, robust implementation that is suitable here, to ensure the deletion. and kinda defeats the purpose of Die(), which is efficiency. That proc was written primarily to be efficient and make use of the garbage collector. If you re-read my post, in fact, that proc will only take effect if the garbage collector didn't delete the object, otherwise it won't and things will work the same as they did before. If you've meant the possibly extraneous istype() check, you can simply use if(X && istype()) to avoid it when unneeded. I just have to defend my post [...] Thank you for your understanding. :P That's fine; same here. Especially considering since I guess this wouldn't be a useful topic at all if it wasn't for this discussion, especially since the author didn't post yet as to whether he solved his problem or possibly had issues following his probable direct copipasting of your code (no, I'm not saying your code is bad by this). |
How was my post meaningless? I gave him a resource to look at so he can sharpen the coding on his own. Meaningless would be what I first said, but leaving out the part which talks about the demo.
-Drew Edit: THIS is a meaningless post, but I had to respond D: |
I didn't say your post was meaningless, I said Flame Sage's post wasn't more meaningless than it. Both had meaning, and Flame Sage is correct in saying that people are not quite intended to request code in this main forum, and if they want that then they should use a guild forum (or something else) or look for a programmer (such as in Classified Ads) instead. And, even if it wasn't truly the OP's meaning, it is also customary to spend more time and more than a single sentence in your topic/post, so people do have a better idea of your meaning/question/issue/etc.
|
Because what I've said in the part you've quoted. But no matter, I just needed to say what I think, it's okay if you disagree. There is no reason the summoner would get stuck because his movement did not change his location. If that's the case, the creature would not change its location either. If that's what you meant. I'm going to have to disagree here. It's a quick, robust implementation that is suitable here, to ensure the deletion. Eh, not completely true (or valid as an argument). You can make things safer by being aware of possible issues and accounting for them, like I've suggested. To be safer, you could simply use del straightaway, but of course we want to avoid that as it is considerably less efficient by comparison. That proc was written primarily to be efficient and make use of the garbage collector. If you re-read my post, in fact, that proc will only take effect if the garbage collector didn't delete the object, otherwise it won't and things will work the same as they did before. If you've meant the possibly extraneous istype() check, you can simply use if(X && istype()) to avoid it when unneeded. Lazy does not contradict robust. Your method is robust, but it goes against the purpose of this idea, which is efficiency over safety. If we're going to do all this to ensure the object is deleted, we might as well call del() and do it ourselves. |
DivineO'peanut wrote:
Your method is robust, but it goes against the purpose of this idea, which is efficiency over safety. I don't think so, since the purpose of my method instead of only a single del() instruction is the efficiency. If I was only concerned about safety I'd do the latter. Instead, I use something that has both safety and efficiency (the only mention-worth penalty or slowness in it is the little time taken to run the proc and locate() call, which should be fast and negligble, especially the \ref-find version). If we're going to do all this to ensure the object is deleted, we might as well call del() and do it ourselves. Which is what I'm doing, but only if the object wasn't already deleted. |
I don't think so, since the purpose of my method instead of only a single del() instruction is the efficiency. If I was only concerned about safety I'd do the latter. Instead, I use something that has both safety and efficiency (the only mention-worth penalty or slowness in it is the little time taken to run the proc and locate() call, which should be fast and negligble, especially the \ref-find version). The difference between manually calling del() or Die() is not as large as you might think, and calling ensureDel(), which uses alot of expensive things such as locate(), spawn() and istype() counters any benefit that might be gained. Also, I find it strange that you choose to argue about my code, where it is merely a demonstration of how one might apply my instructions. Why are you so concerned about its design ethics when it is not even meant to be used? "Precisely because it is an example good technique should be shown," I predict you say, but this is not the place nor the time to discuss the definition of good technique. |
DivineO'peanut wrote:
The difference between manually calling del() or Die() is not as large as you might think, and calling ensureDel(), which uses alot of expensive things such as locate(), spawn() and istype() counters any benefit that might be gained. Calling del() causes looping through (and comparing&setting) every variable/list that uses the object in your game, so that would depend on the "memory size" of your game. I doubt that spawn() and that locate() are entirely slower, but on those kind of things you can't say much more without clocking it. The istype() was also a mistake on my part from being used to use it, but X.type == type is actually more suitable for that proc, which is also faster. Why are you so concerned about its design ethics when it is not even meant to be used? Obviously, we were arguing about the design of how you should handle deletion of atoms, not your code specifically, which is not meant to be used (which also BTW won't stop it from being, but that is unrelated). |
Calling del() causes looping through (and comparing&setting) every variable/list that uses the object in your game, so that would depend on the "memory size" of your game. I doubt that spawn() and that locate() are entirely slower, but on those kind of things you can't say much more without clocking it. The istype() was also a mistake on my part from being used to use it, but X.type == type is actually more suitable for that proc, which is also faster. del() would be called anyway in the reference counting. The only reason Die() is better than del() is that it doesn't get called manually, which is a minor difference. I'll check the exact difference and post the results. Obviously, we were arguing about the design of how you should handle deletion of atoms, not your code specifically, which is not meant to be used (which also BTW won't stop it from being, but that is unrelated). That is not what I meant, but nevermind. |
I don't understand what you mean. If an object loses all references to it, it is only deleted and 'del' or a similar behavior does not occur.
|
Try to come up with some code yourself, we can probably help you fill in the gaps in the programming.