I'm trying to have my attack code add experience to a certain skill everytime it's used. The problem is, that I don't know how I can tell BYOND this:
When Weapontype X is equipped and attacked with, add X experiance to the corrosponding skill
EX: A sword is equipped. An attack is made, and byond adds X experiance to the sword skill.
I'm sure there's a way to set this up with vars, but I'm not sure the best way to go about this. Any help?
~PAK
1
2
ID:166704
Jun 27 2006, 12:50 am
|
|
In response to Shoe
|
|
But how would I get it to check the weapon type after an attack without a whole bunch of "If" statements? Or is that unnavoidable?
|
In response to Pakbaum
|
|
mob/verb/Attack() or sometin like that ... |
In response to Ripiz
|
|
Thanks but I'm saying the player's corrosponding skill increases, not the weapon. So when you use a sword to attack, YOUR sword skill increases, if you use a polearm, your polearm, etc.
|
In response to Pakbaum
|
|
You could just run equipped.type through a switch() statement or something....
|
In response to Jmurph
|
|
Can you give me an example of what you mean?
|
In response to Pakbaum
|
|
Pakbaum wrote:
Can you give me an example of what you mean? switch(equipped_item.type) |
In response to Shoe
|
|
Ok, this is what I have now.
mob/verb But it's not increasing after the attack, what am I doing wrong? |
In response to Pakbaum
|
|
The first thing you need to do is to discard that code you just posted; it is based on several critial design errors. The next thing you should do is read the Byond-Wiki (Bwicki) page BasicCombatSystem. This page discusses many of the problems in your attack system, like how you're subtracting the target's hp in the attack verb. This may not seem like a large problem, but it is the exact sort of thing which will prevent you from being able to add features like 'equipment proficiency' to your program.
Once you've reworked the attack system, we can get to work on adding weapon proficiency. By reworked, I mean that you at least have separated hp deduction and death from the attack verb, and have put them into their proper procs (hit() and adj_hp(), for example). Now your code should look something like this: mob The first thing you should note is that this code does not work, and is not complete. This is simply a design of a system and how it should work, not the actual code for that system. The second thing that you should notice is that there's a lot of seemingly usless procs; for instance, all hit() seems to do is call adj_hp(), and adj_hp() doesn't seem to do anything that couldn't have been done directly in attack(). But these proc are very important, they can be redefined by different mob types to do special actions when: they attack, they are hit, they loose hp, they die. You now have tons of options, which translates to features in your program. Imagin that you want one of your mobs, a ninja for example, to counter attack whenever attacked. This is simple with my version: mob/ninja/hit(var/mob/attacker, var/damage) Imagin what this would look like in the other code: mob/verb Ack! Even with the over simplification, it's still a monster. The code for your attack system will be over a mile long. Anyway, let's move on to your original question, equipment proficiency. We'll start with attacking (yes, I'm going to give you proficiency with defending, too!). Instead of keeping a horribly long switch statement with each type of weapon, and having to hard code each new type when you add it, we'll use an associative list (Lummox JR has a great article on associative lists). Each item in the list will be a string (text surrounded by quotes, such as "polearm"), and each item will be associated with a numerical value representing how good the player is with that type of weapon. An example entry might look like this: "staff" = 5 That would mean that the mob's proficiency with staff type weapons has a value of 5. Each weapon will have a variable saying what type it is. obj/weapon I don't know about you, but I think that's super snazzy. The best part is that you can add as many weapon types as you want, and you'll never have to recode anything! You could add the following snippet, and you'd never have to go back and edit a switch statement: obj/weapon/squid With a little bit of work, the above could be changed into armor proficiency, or how good you are with using your armor. Or, you could add defense proficiency, or how good you are at defending against different types of weapons. Or you could add both! Let's look at something else that can be done, though. Something much more interesting and useful. What if the squid weapon in the above example was supposed to confuse the target whenever it attacked? Instead of adding a switch statement to the attack verb to check what we're attacking, we'll give the weapon it's own way of doing what it wants. mob/proc/attack(var/mob/target) And there you have it, a custom squid weapon. The same priciple applies to all custom types. A vampire can override it's attack() proc in order to steal health from the victem. Chainmail shirts can defend better against being attacked by bladed weapons (/obj/armor objects would need their own 'hit()' or 'defense()' proc, to be called somewhere in target.hit()). The sword_of_pwnage can even decide if you are 1337 enough to wield it: obj/weapon/sword_of_pwnage |
In response to IainPeregrine
|
|
when it comes to battle systems, i'd rather keep my 'attack' verb one. it is awfully confusing when your code is speard around with items =/
|
In response to Shoe
|
|
Shoe wrote:
when it comes to battle systems, i'd rather keep my 'attack' verb one. it is awfully confusing when your code is speard around with items =/ Simply put, then your games will be featureless. Imagin what your code will look like when you have ninjas/indians, ice/fire armor, and swords/axes? What if ninjas are weak against fire and excell at using axes, but indians don't use ice armor well and defend well against swords? Your attack 'verb' will look like this: if(ninja && fire && sword) ... if(ninja && fire && axe) ... if(ninja && ice && sword) ... etc. Every time you add a new object you'll have to go back to each condition and make sure that it's hard coded to include the new type. Each time you add a new feature, you'll have to completely redo the entire system. Battles require a combat system, and not just an 'attack verb'. A system is a group of interrelated objects, functions, and variables that work together to perform a task or a set of related tasks. A verb is one way in which the user interacts with a system. The bottom line is that objects are supposed to own the methods (procs and verbs) that define their behavior. If a mob is able to attack, it should define the way in which it attacks. If a mob is able to be hit, it should define how it reacts to being hit. If a weapon should do something special when it attacks, the weapon should define that, not some arbitrary third party object. Why should an attacking mob define the way a turf reacts when a potion is droped onto it from a player who just was killed by the attacking mob? mob/verb/attack() |
In response to IainPeregrine
|
|
I completely agree. It would be so much easier to just have a proc that checks something. You would never have to change the proc, but if you had it all in one place like an attack verb, you'd have to keep changing it, over and over again, like iain said.
|
In response to IainPeregrine
|
|
IainPeregrine wrote:
Shoe wrote: > mob/verb/attack() when i used the term 'attack' verb, i meant a verb that contained all of my needs when i 'attack'. but i have to agree on this one, when it comes to complicated battle systems such as this. but i still think simple battle systems should keep it in one verb and maybe a proc or two. |
In response to Pakbaum
|
|
I see that you're using a text variable to describe the weapons' classes; however, I think it would be much easier to instead create equipment subtypes. Also, it's probably better to have the player mob owning a reference variable to its equipped weapon. I recommend checking out hub://wizkidd0123.equipmentdemo.
|
You need to be using subtypes.
Instead of: obj/Sword You should use a more specific path like this: obj/Items/Weapons/Swords/Broadsword (It may seem tedious but you will find things like these can save you a lot of time as opposed to hardcoding everything.) When you need to check the type of a weapon, you simply need to check the paths: if(Player.Weapon.type in typesof(/obj/Items/Weapons/Swords)) Note: Don't directly copy anything; This code takes in a few assumptions. |
In response to Hobbesx
|
|
Well, if your trying to do it based on uses, why not pull it off as if it were a mob? Set it EXP and maxEXP and have a level up proc for it, increase its damage or something. I'm just giving an example for his first post, I didn't read all of the others.
|
In response to IainPeregrine
|
|
Ok ok, I've reworked it, but because I'm not exactly sure how some of the things work, could you explain anything I've done wrong? And I'm also aware that ya'll may think it may have well been copied and pasted, but I typed it all out to understand it better.
//ATTACK Thank you for any help. And BTW: runtime error: Cannot read null.wtype proc name: attack (/mob/proc/attack) usr: Pakbaum (/mob) src: Pakbaum (/mob) call stack: Pakbaum (/mob): attack(null) Pakbaum (/mob): Attack() Is what I get when I try it out. |
In response to Pakbaum
|
|
Pakbaum wrote:
Ok ok, I've reworked it, but because I'm not exactly sure how some of the things work, could you explain anything I've done wrong? And I'm also aware that ya'll may think it may have well been copied and pasted, but I typed it all out to understand it better. Good. From the looks of your code, and the changes you made to it, it seems that you made an earnest effort to learn and understand what you're doing. The immediate cause of your runtime error is (probably) that the attacker didn't equip a weapon; hence, "weptype" would be "null" (nothing) and the program can't access "null.wtype". One of the first things that we can do to fix this is to check if the attacker doesn't have a weapon, and do some sort of default action if he doesn't: attack(var/mob/target) Also, the name of your weapon storing variable is misleading. "weptype" would mean that the variable stores a weapon type, something like "polearm" (text describing the type) or /obj/weapon/polearm (an actual DM type path). Instead, the weptype variable should be storing a data object, something like a mob or an obj. A better name would be something like "equiped_weapon" or just "weapon". I would strongly suggest that you change the name, and more importantly, that you come to understand the difference, it is a very important concept. So, why is weptype null? Because we never set it to any value: obj/weapon/weptype That line doesn't actually make a new object, it just defines a variable and tells the compiler that it will be of type weapon; right now it's value is null, we need to store an actual object in that variable. This is normally done in an "equip" verb: weptype = weapon_object() I see that you set weptype equal to "wtype" down in the Arm function (/obj/weapon/verb/Arm). If wtype is text (like "polearm") then you'll get errors in your attack function when you try to access "polearm".wtype Instead, set weptype to the actual object that is being equiped: usr.weptype = src Now we can access it's variables and functions. That should be enough to fix the runtime error you experienced, but there's a couple other things in this code I think are worth looking at. In /mob/attack_base you never check if a target wasn't found. If a player calls the verb attack_base while no one is in front of them, then locate will return null, and target will be set to null. So we need to check if a target was found, and bail out (exit, return) if there was no one there: attack_base() In /mob/hit you set the blocked variable equal to a booleen value (0 or 1). This is great considering that the word 'blocked' would mean the variable was either TRUE (blocked) or FALSE (not blocked), so that later you could check if(blocked). The problem is the next line, where you are subtracting blocked from damage. blocked can only ever be 1 or 0, so unblocked_damage will always be either damage, or damage-1; I don't think this is what you wanted. Because I don't know how attackrating or dodgec work, I can't suggest what to do; I might have been able to suggest something had 'dodgec' a more descriptive name. What is damageb (in /obj/var)? Battle_damage, or maybe damage_base? I'd suggest a more descriptive name, it could save you a lot of time six months from now. Similarly, armr and armrn don't tell me much about what they do, or how n makes them different. Thank you for any help. No problem, it's great to help someone who's making this kind of effort to learn the language. |
In response to IainPeregrine
|
|
So how would I manually add the proficiency? So that when character creation is going on, and the user chooses the weapon, they can start out with that proficiency?
New code: mob |
1
2
give the item a variable which determines its skill type.
ie