ID:175337
May 6 2003, 3:13 pm
|
|
why doesusr disapears when attacking?
|
May 6 2003, 3:25 pm
|
|
Because usr's icon does not have the icon state you set the icon_state variable to.
|
In response to Garthor
|
|
Garthor wrote:
Because usr's icon does not have the icon state you set the icon_state variable to. i dont think soo i have a attack icon_state for all characters |
In response to Nave
|
|
Then you must've misspelled something. (It would help to show your attacking code!)
|
In response to Crispy
|
|
Crispy wrote:
Then you must've misspelled something. (It would help to show your attacking code!) mob/PC/verb/Auto_Attack(mob/M as mob in oview(1)) //If we have Auto_Attack be the only verb capitalized, it will always be the first verb in the battle panel. set category = "Battle" //In this auto attacking proc, we will need to check if the mob is still next to you, and check if the mob has not been deleted yet many times before the proc is over due to the different things that can constantly happen during an RPG. if(istype(M,/mob/PC)||istype(M,/mob/Enemies)) //We only want these two types to be able to be attacked. if(usr.attacking == 0) //Don't want them to attack more than once. while(M in oview(1)) //This is the while statement. It checks to see if M is in oview 1, and if M is, and if it successfully got to the end of the last time it ran through the while statement (if it was already executed) it will repeat whatever is in front of the while() statement. usr.dir = get_dir(usr,M) //This gets the direction from usr to M. flick("[usr.icon_state] attack",src) //This is explained in the Login() proc below. usr.attacking = 1 usr.Preattacking(M) //This will do anything defined in the proc to M before everything else. This is most useful when lots of mobs are defined. //Now comes the math part... var/str = round(usr.Strength / 4) //The usr's strength will be divided by 4 so he can still have high numbers of strength, but still need a good weapon. The round proc is used to round what ever is in its parentheses. That is usually needed only after dividing like here. var/mindamage1 = usr.Min_Damage + str //The usr's minimum damage adds a big plus to the strength, thus making the total minimum damage higher. var/resist = M.Defense + M.AC //Add the opponent's defense to its AC var/resist2 = round(resist / 2) //Don't want the opponent's defense to get too high. var/mindamage2 = mindamage1 - resist2 //Subtract the damage var/maxdamage1 = usr.Max_Damage + str //Do the same here... var/maxdamage2 = maxdamage1 - resist2 var/chance = usr.DEX + M.AGI //Add the usr's DEX to the opponent's AGI... You will see why in a moment. var/chance2 = rand(1,chance) //Select a random number between 1 and how ever many chance came up to be after DEX and the opponent's AGI were added. var/damage = rand(mindamage2,maxdamage2) //Find a random number of damage... if(chance2 <= usr.DEX) //If the random number chance came up with was less than the usr's DEX, then you get to attack. Why? When you add the usr's DEX and the opponent's AGI, that makes an imaginary range, with the last number of usr.DEX being the middle number. If the random number was selected in your range, which can grow larger and larger, you can attack, but if it was selected in the opponent's AGI range, you cannot attack. if(damage <= 0) //Don't want to add HP to the mob, do we? damage = 1 usr << "\red You hit [M] for \blue[damage]\red points of damage." oview(usr) << "[usr] hit [M] for \red[damage]\black points of damage." M.HP -= damage usr.Postattacking(M) M.DeathCheck() else usr << "You attacked [M], but you missed." oview() << "[usr] attacked [M], but missed." usr.Postattacking(M) sleep(Attack_Delay) //The sleep proc is used to delay it by how ever many tenths of a second is defined in the usr's attack delay. Since the while statement doesn't need to be called again, we don't need to use spawn(), which is only used to keep out infinite-loops and delay before executing a new (or the same) proc again. usr.attacking = 0 //this will only happen after the while() statement is through, which means the mob is somewhere else. //Now, to define the some of the stuff that was put in above: mob/proc/Preattacking(mob/M) //This will be used if say, the mob has thorns. In the mob's coding, you set it's Preattacking setting to damage usr. mob/proc/Postattacking(mob/M) //Same, but this time it will do it after damage was dealt and the damage messages are sent. mob/proc/DeathCheck() //We are going to use src in this because it was called like this: "M.DeathCheck()" well, now M is src because M is the one that called it. if(!src.client) //Check to see if this is not controlled by a person. Only actual players have the client var not set at null. //If not... if(src.HP <= 0) oview(src) << "[src] was slain by [usr]!" //usr is the person who used the Auto_Attack verb so usr will stay that person. if(usr.client) //Some enemies might attack each other, and you don't want to level them up, right? if(usr.groups == null) //This is explained in the grouping section. This means "if the usr does not have a group." usr.EXP += src.EXP_Give //Give the amount of EXP the enemy had to give. if(usr.EXP >= usr.EXP_To_Next) usr.EXP -= usr.EXP_To_Next usr.LevelUp() while(usr.EXP >= usr.EXP_To_Next) //Say if you kill a huge mob when your level 1, and the mob's EXP_Give is enough to level you 12 times... Well, this is where it works. usr.EXP -= usr.EXP_To_Next //It takes it down the amount of EXP that was needed. usr.LevelUp() //Wow! You leveled up again! sleep(1) else var/Groupies = list() //This will be a list of your group members. for(var/mob/PC/Pc in world) //This will check all the PCs in the world. if(Pc.groups == usr.groups) //If both their groups vars are the same (it only is if they are in each other's group..." Groupies += Pc //Add that group member to the Groupies list. var/newexp = round(src.EXP_Give / length(Groupies)) //This will define a new var called "newexp." It is the mobs given experience divided by how ever many group members you have. for(var/mob/PC/Pc in Groupies) //For everyone in your group, give them experience like you did when it was just you: Pc.EXP += newexp if(Pc.EXP >= Pc.EXP_To_Next) Pc.EXP -= Pc.EXP_To_Next Pc.LevelUp() while(Pc.EXP >= Pc.EXP_To_Next) //Say if you kill a huge mob when your level 1, and the mob's EXP_Give is enough to level you 12 times... Well, this is where it works. Pc.EXP -= Pc.EXP_To_Next //It takes it down the amount of EXP that was needed. Pc.LevelUp() //Wow! You leveled up again! //We want everyone to get their levels quickly so we won't sleep here. if(src.Spawned_By != null) //If the mob was spawned by something src.Spawned_By:My_Spawned = null //Make their spawn point's var null as defined in RPGTutorial. usr.Postdeath(src) del(src) else //If the mob is a player character... if(src.HP <= 0) world << "[src] was slain by [usr]!" //We want a lot more people to hear this. //Killing a PC won't give you any EXP... //The PC needs to be penalized for dieing... Do this by getting rid of some of his/her EXP... But only do this if it was an enemy that killed him/her. if(istype(usr,/mob/Enemies)) src.EXP -= round(src.EXP_To_Next * 0.20) //Subtract 20% of the victim's needed EXP. if(src.EXP < 0) src.EXP = 0 //If it is at a number that it shouldn't be (negative) reset it. src << "You lost some experience!" //EXP can get annoying to lose, so if your game is a game that the player is going to die a lot, it's best to lower the amount of EXP lost, or else use gold instead if gold isn't as important. //Reset the PC. src.HP = src.MAX_HP src.loc = locate(3,4,1) mob/proc/LevelUp() //In this proc, usr called it so now usr is the src. if(src.client) //Check to see if it is a player... if(src.Level < 99) //Can't go past level 99! if(src.Class == "Warrior") src.Strength += rand(2,3) * src.Level //Strength will come by greater amounts if the player is a higher level. src.Defense += rand(1,3) * src.Level src.AGI += rand(1,2) * src.Level src.DEX += rand(1,3) * src.Level src.MAX_HP += rand(4,8) * src.Level src.MAX_MP += rand(2,3) * src.Level else src.Strength += rand(1,2) * src.Level src.Defense += rand(1,2) * src.Level src.AGI += rand(1,2) * src.Level src.DEX += rand(1,2) * src.Level src.MAX_HP += rand(3,7) * src.Level src.MAX_MP += rand(4,6) * src.Level src.HP = src.MAX_HP //Reset their HP stats back to full... In other words, completely heal them. src.MP = src.MAX_MP src.Level += 1 src.EXP_To_Next += src.Level * 150 if(src.Level == 99) //This will only be done once right here because a level only comes once. src << "<FONT color = blue size = +1>You have reached level 99! The largest level possible!</FONT>" else src << "<FONT color = red size = +1>You have gained a level!</FONT>" src.Save_Character() /* We have now gotten through the first part of it all. Now lets define some of the more basic procedures for a mob. First, lets start with the Login() command: */ world/mob = /mob/PC //This makes the default mob to login to a PC. mob/PC/Login() //Let's get started: var/I = input("What would you like to do?","Logging in:","Continue") in list("Continue","Create New Character") //The input command is made so you can get information from whoever is defined and make the variable defined before the input() that value. if(I == "Continue") //If the player selected continue... var/savefile/F = new(client.Import()) //Ok, this is an advanced concept so if you get confused by this, skip it because all you really need to know is the format: savefile is a type like mob, obj, turf, area, atom, and so on are. When you create a new savefile, it is saved in the area specified (in this I do not specify a file path because client.Import does it for me.). client.Import will save it in your \BYOND\users\[Your name here]\Keyinfo\ folder... When I get to client.Export (the second part of this, the actual saving of it in other words) I will explain this some more... if(F) //If there was a file there... Read(F) //Read the mob specified in the file. The Read() proc reads all vars in the mob in the savefile (tmp vars are not saved, which I will show you a little later in the grouping procedures section.). else usr << "You don't have a character saved!" I = "Create New Character" //Turn I back to "Create New Character" so when it gets to that part of the proc below, it will make the person create a new one. if(I == "Create New Character") //If they selected to create a new character or if it couldn't find a savefile which is defined above... Name_Character() //Call this proc which is defined below the Login() proc. This is the same as calling src.Name_Character(). var/C = input("What would you like your character to be?","Class:") in list("female Warrior with pike","Wizard","Male Knight") //Ditto but with class. if(C == "female Warrior with pike") //Now, to set stats... Because I defined icon_state in a special way above, I wont need to do anymore defining of it. icon = 'warrior_f1.dmi' Min_Damage = 1 //A warrior's stats: Max_Damage = 3 Attack_Delay = 4 HP = 30 MAX_HP = 30 MP = 10 MAX_MP = 10 Strength = 2 Defense = 2 AGI = 3 DEX = 4 EXP_To_Next = 100 if(C == "Male Knight") icon = 'knight_m4.dmi' Min_Damage = 1 //A wizard's stats: Max_Damage = 3 Attack_Delay = 4 HP = 25 MAX_HP = 25 MP = 20 MAX_MP = 20 Strength = 1 Defense = 1 AGI = 2 DEX = 3 EXP_To_Next = 100 if(C == "Wizard") icon = 'wizard.dmi' Min_Damage = 1 //A wizard's stats: Max_Damage = 3 Attack_Delay = 4 HP = 25 MAX_HP = 25 MP = 20 MAX_MP = 20 Strength = 1 Defense = 1 AGI = 2 DEX = 3 EXP_To_Next = 100 loc = locate(4,4,1) //Puts the player at the starting position. |
In response to Nave
|
|
First of all, you don't have to show all of the code, just the part of the code you are having problems with (I didn't read it, too much :-)) also, yous the dm html when doing it, it looks better, like this
<dm> ~STARWARSPOWER~ |
In response to Starwarspower
|
|
Starwarspower wrote:
First of all, you don't have to show all of the code, just the part of the code you are having problems with (I didn't read it, too much :-)) also, yous the dm html when doing it, it looks better, like this <dm> ~STARWARSPOWER~ that is the attack code!!!help! |
In response to Nave
|
|
help plz?
|
In response to Nave
|
|
No, this is the attack code... Or at least the only part of it that matters (I'm taking out the commenting and reindenting things to fit better on the boards) The rest of the stuff is just supporting procs and such...but for the problem you're having, this verb is the only one that matters... Learning how to find specific areas of code that problems lie in will be critical for you to be able to code well in the future... The reason this verb is the culprit is because of the line in bold text below:
mob/PC/verb/Auto_Attack(mob/M as mob in oview(1)) set category = "Battle" if(istype(M,/mob/PC)||istype(M,/mob/Enemies)) if(usr.attacking == 0) while(M in oview(1)) usr.dir = get_dir(usr,M) flick("[usr.icon_state] attack",src) usr.attacking = 1 usr.Preattacking(M) var/str = round(usr.Strength / 4) var/mindamage1 = usr.Min_Damage + str var/resist = M.Defense + M.AC var/resist2 = round(resist / 2) var/mindamage2 = mindamage1 - resist2 var/maxdamage1 = usr.Max_Damage + str var/maxdamage2 = maxdamage1 - resist2 var/chance = usr.DEX + M.AGI var/chance2 = rand(1,chance) var/damage = rand(mindamage2,maxdamage2) if(chance2 <= usr.DEX) if(damage <= 0) damage = 1 usr << "\red You hit [M] for \blue[damage]\red points of damage." oview(usr) << "[usr] hit [M] for \red[damage]\black points of damage." M.HP -= damage usr.Postattacking(M) M.DeathCheck() else usr << "You attacked [M], but you missed." oview() << "[usr] attacked [M], but missed." usr.Postattacking(M) sleep(Attack_Delay) usr.attacking = 0 Now, the reason that that line is the problem, is because that is the only line in the attack system that is messing with the player's icon... And that's the most likely reason that they disappear... Above, someone suggested that you don't have the proper icon_state in the mob's icon... That is my guess as well... You answered that all of your characters have "attack" icon_states, but let's look at that line again: flick("[usr.icon_state] attack",src) flick() changes the target's icon_state to whatever is listed in the quotes, and then back again after it is done (a single frame icon_state will be almost instantaneous, so it's best to have an animated state, or at least an animated file with the frame delay set to whatever duration you want the state to be displayed... otherwise, direct changes to icon_state should be used, with the appropriate changes back when the attack is done) But anyways, what is happening here, is that the code is telling the program to display the "[usr.icon_state] attack" icon_state... Simply naming the icon_state "attack" isn't the same... The bit in brackets needs to be in the name, too...and it has to be whatever icon_state the player is currently in... For instance, if the player's icon_state is "human_1", then in that mob's icon file, you need to name the attack icon_state as "human_1 attack", instead of just "attack"... However, looking at your code, it would seem that your players don't even have a default icon_state... So basically, the whole thing is unnecessary... You could go in and change the problem line to just: flick("attack",src) And then name all of your corresponding icon_states as "attack" (like I assume you're already doing at this point) And I've noticed something... You seem to be using demo or library code for this... It looks like it was written by someone other than yourself... In that case, it's best for you to read through it and try to understand how it works, instead of just slapping it into your game, and getting all kinds of problems that you don't know how to solve because you never bothered to try to understand the code you're using... Also, the whole thing is rather messy... First of all, it uses "usr" all over the place, when it should be using "src"...but that's another matter entirely...lol And also, I imagine that most of what I've typed up there seems a bit too complicated... The trouble is, that's about the only way to explain things...lol |
In response to SuperSaiyanGokuX
|
|
omg thank you so much!
|