ID:1377616
 
(See the best response by Ter13.)
//no code


Hey, I've been scouting varies posts looking for how to codes varies attacks but I have not been able to find any help for it. I'm trying to make a one piece anime fighting game. I'm focusing right now on just getting on DF coded so I can see how it needs to be coded I'm trying to code the rubber pistol, but I can't think of how to do it. I want it to hit 2 blocks out
xxxx
xo--
xxxx
o being the player and -- is the punch.
any help please.


Best response
Well, for starters, it all really depends. Most people implement attacks in some sort of datum or object.

Below, I will show you how to implement a singleton attack system:

Singletons are single-reference objects, that only need to be created once.

This means that if we have 100 attacks in the game, we only need to

This is not the best way to ago about this, but it really doesn't matter, because it works better than about 90% of what else you are going to see other people using out there. Optimally, I'd prefer to not use per-type attacks, and instead build *kinds* of attacks, then initialize them with different values that affect the outcome.

var
list/attacks = list()

attack
parent_type = /obj
proc
use(var/mob/user)
learn(var/mob/learning)
learning.knownattacks[src.name] = src
New()
global.attacks[name] = src
..()
Del()
global.attacks.Remove(src.name)
..()


Now that we have all the groundwork set up, we can start defining some attacks, as well as populate the global list of available attacks.

attack
test1
name = "attack"
use(var/mob/attacker)
var/turf/t = get_step(get_step(attacker,attacker.dir),attacker.dir)
if(t)
var/mob/target = locate(/mob) in t
if(target)
target.hp -= 50
target << "You got hit hard by [attacker]!"
target.deathCheck(attacker)
test2
name = "doesnothing"
use(var/mob/attacker)
attacker << "this does nothing!"

proc
buildAttacks()
new/attack/test1()
new/attack/test2()

world
New()
. = ..()
spawn()
buildAttacks()


And then we have to set up our mobs to be able to use attacks.

mob
var/tmp
list/knownattacks = list()
proc
attack(var/atkname)
var/attack/a = knownattacks[atkname]
a.use(src)
Login()
var/attack/a = global.attacks[global.attacks[1]]
a.learn(src)
. = ..()
//since we marked knownattacks temp, but we do want to save attacks:
Write(var/savefile/F)
..()
F.cd = "attacks"
for(var/v in src.knownattacks)
F << v
F.cd = ".."
Read(var/savefile/F)
..()
var/v
var/attack/a
F.cd = "attacks"
while(!F.eof)
F >> v
a = global.attacks[v]
if(a)
src.knownattacks[v] = a
F.cd = ".."


The reason I set up known attacks to be temp, is because if we don't, you'll wind up saving all the attacks in a savefile whenever you save your players. You don't need to do this. You actually only need to save the name of each attack known, so you can get away with just passing the names into the savefile, then reloading the string name, and searching the global attacks variable in order to find the attack again after the player's being loaded.

This will cut down on your savefile size, and allow you to remove attacks from the game later.

Of course, you are still going to need a way to show the attacks to the player so they can click on them and use them.

For a quick and dirty way to do this:

attack
Click()
src.use(usr)

mob
Stat()
statpanel("attacks")
for(var/v in src.attacks)
stat(src.attacks[v])


This is obviously, a very, very simple system, but it should at least get you there. Also, your attacking things from two tiles away? Yeah, that's what test1 does.
Alright I'll try this and see how is feels. Thanks.
Ter for your first example of setting up the global attack.

When you are using src what would that he refrencing to the one calliing the attack atom or the attack atom itself?
src is always the object that we are currently operating within.

Meaning if the code is located in the attack object, src is the attack object.
In response to Ter13
I'm sort of curious as to why you locate() a turf then locate() a mob in the turf when searching for a mob. Any reasoning behind that instead of just doing:

var/mob/target = locate() in get_step(attacker, attacker.dir)
if(target)
So we don't wind up calling locate() in null.
In response to Ter13
True enough, I s'pose I never thought of it that way. Learn something every day.
I am confused by this part:

《Dm》
Learning.attack[src.name] =src

《/dm》

So this would make the attack atom be added but it seems strange to me could you explain?
It's pretty self-explanatory.

learn is an attack proc, which when supplied with a mob as an argument, adds the attack to the mob's list of known attacks.
I understand that it is the src part and so I understand it makes it the src name but why are we making that equal to the src?

Is it so that the mobs list index refrences back to the original global proc?
Like an associtive list?
Yes, we're not creating an attack per owner. We're creating a SINGLETON, as I explained in the prior posts. There's no reason with this system to initialize more than one object per attack type. Thus, we can reference the attacks in the mob's variables, rather than creating a new object and adding it to the mob's list of attacks.
In response to Ter13
Ter, I have an even better question! When you make the parent_type /obj, you essentially are creating an object. Therefore, my question is why would one do so to a datum? The only explanation I can think of is to save typing and keep the object tree looking tidy.
As in ... why would you set parent_type = /datum? You wouldn't, I suspect, as that is implicitly the case anyway. The below produce the same type path:

TestDatum

TestDatum
parent_type = /datum // This was implicit, above.


I'm not sure there is particularly ever a scenario where doing the latter would produce a different result, unless you're threading other types in, as IainPeregrine once demonstrated for BYOND 'interfaces'.
In response to Ss4toby
Ss4toby wrote:
Ter, I have an even better question! When you make the parent_type /obj, you essentially are creating an object. Therefore, my question is why would one do so to a datum? The only explanation I can think of is to save typing and keep the object tree looking tidy.

It's a preference thing.

I don't like objects that shouldn't be mapped getting in my object trees.
In response to Ter13
Well, you can hide objects from the tree in Build settings.
In response to Kaiochao
Kaiochao wrote:
Well, you can hide objects from the tree in Build settings.

I've been here for over 12 years... And I just now found this out? Thanks for that.

I still like the shorthand, though.
Sorry for the no feedback on my situation. I've been busy round the place. Okay now I'm pretty much hitting a coders block, I haven't a clue what to do or where to go on my situation. I have friends that play BYOND but none that code so I can't really get help from them on this. And I really want to get this game running, I just don't believe I have the knowledge to do it.
Make. A small casual game as side project then come back to main project. Just keep learning.
Ter why do you use procs instead of verbs?
Page: 1 2