ID:272701
 
Okay I'm in the final stages of this little object :D I added another bump possibility so that the usr can train.

obj/Weaponry
density = 1
layer = MOB_LAYER
Knife
icon = 'Knife.dmi'
Price = 500
var/Material
Bump(atom/A)
var/mob/O = Owner
if(ismob(A))
var/mob/M = A
var/dmg = round(O.NeedleSkill + O.Taijutsu)
switch(Material)
if("Bronze") dmg*=1
if("Iron") dmg*=1.5
if("Steel") dmg*=2
M.Health -= dmg
view(M)<<"[M] was hit by \a [src] for [dmg]"
O.NeedleEXP += M.Level
O.NeedleLvlUp()
M.Death(O)
if(istype(A,/obj/Training/Training_Log))
var/rndm = rand(20,30)
O.NeedleEXP += rndm
O.NeedleLvlUp()
O<<output("<font size=1>You gained [rndm] Needle experience","Crap")
del(src)
New()
src.name = "[src.Material] Knife"
src.suffix = "([Amount])"
..()
Bronze
Material = "Bronze"
Amount = 5
Iron
Material = "Iron"
Amount = 5
Steel
Material = "Steel"
Amount = 5
verb
Drop()
if(!src.Amount) del(src)
var/drop = input("How many do you want to drop?\n- You have [src.Amount] [src]\s","Drop") as num
if(drop > src.Amount || !isWhole(drop) || drop <= 0) return
src.Amount -= abs(drop)
src.suffix = "([src.Amount])"
var/obj/Weaponry/Knife/D = new(usr.loc)
D.Amount = drop
if(!src.Amount) del(src)
usr.AutoSave()
Get()
set src in oview(1)
var/obj/Weaponry/X = locate(src.type) in usr.contents
if(!X)
Move(usr)
suffix = "([src.Amount])"
else
X.Amount += src.Amount
X.suffix = "([X.Amount])"
del(src)
usr.AutoSave()
Throw()
for(var/obj/Weaponry/Knife/K in usr.contents)
var/obj/Weaponry/Knife/X = new(usr.loc)
X.MoveDelay = 1
X.Owner = usr
walk(X,usr.dir)
K.Amount -= 1
K.suffix = "([K.Amount])"
if(!K.Amount) del(K)
spawn(50) del(X)
Seems generally okay at a glance. Some tidbits:
--In Drop()'s input(), I'd allow a cancel button ( <_< ) and set a convenient default value for the number. That would be either 1, or the amount, depending on your preference.
--Get rid of the for() loop in Throw! Uaagh! Also, you may want to realistically allow picking up of the thrown knife or as such, if it's done fast enough. If you want this, you could tweak things: first, move the timer off to the projectile's Bump(), so it only begins counting after it hit something and stopped. Then, make the time it takes to disappear slower; but if a player picked it up during that time, don't delete it. An imperfect but okay way of checking for this is checking the projectile's loc's type.

--*: (Extra?)
I'd really handle the item stacking system through the movement system instead, in Entered() and Exited() and as such. You could also implement an inventory or weight limit by using Enter() and Exit().
In response to Kaioken
Forgot that the Throw() verb still had the for loop >.<

You told me to get rid of the num|null on the input()

How do I set a default number in the input()?

I can see a problem with putting the timer till it deletes itself in the Bump(). When it hits a null turf, the timer won't start since it has nothing to "bump" perse. Or so I believe from experience.

How would I use Entered() and Exited() to control item stacking?

I plan on doing a weight system later on in development really. So as of now, just the above :D
In response to Mizukouken Ketsu
Mizukouken Ketsu wrote:
Forgot that the Throw() verb still had the for loop >.<

You told me to get rid of the num|null on the input()

No, I told you to just watch out for what it returns (null), because you don't have checks for it - if I'm guessing correctly, the isWhole() check won't catch it, though it might. Anyway-
if(!drop || ...) return


How do I set a default number in the <font size=4>input()</font>?

Cough. ;)

input(Usr=usr,Message,Title,Default) <small>[as Type in List]</small>

You could put a title along the way, though you don't have to (you can put either null or "" there, or just leave it blank in that spot).

I can see a problem with putting the timer till it deletes itself in the Bump(). When it hits a null turf, the timer won't start since it has nothing to "bump" perse. Or so I believe from experience.

You mean the edge of the map, yes, that doesn't call Bump(). The way I'd check for this is in the projectile programming itself; you can either check if the coordinates are at the edge (basically but not quite, 1 or world.max/y) or use a convenient get_step() call for the turf in front - if there is none, it will return false.

How would I use Entered() and Exited() to control item stacking?

obj/item
var/amount
verb
Get()
set src in oview(1)
if(src.Move(usr)) //if movement succeeded
if(src.amount)
usr << "You pick up [src.amount] [src]\s."
else usr << "You pick up [src]." //insert "the" as needed
Drop() //you may design this a little differently.
//set src in usr //default
var/obj/dropped_obj = src
if(src.amount)
//ask player how many to drop, etc...
//...
dropped_obj = XYZ
//XYZ is the new object we're dropping, or if \
we're dropping everything then it's src

if(dropped_obj.Move(usr.loc))
usr << "You dropped..."
//make sure 'XYZ' is created inside the player's \
inventory in case of movement failure. you could \
also reverse the item separation in case of failure\
but it's not required.

proc/IsEqual(obj/item/O)
/*this is a proc to check if 2 items are equal
enough for them to be merged together (by increasing
amount). this is a rather important step to make if
you do item object instance customization yourself, or
allow players to do it to some extent (eg item forging
system, choose custom stats/name/icon...
if this returns 1, it's equal as far as we're concerned,
and can be merged*/

var/list/checked_vars = list("type","name","desc","icon","icon_state"
"strength/power","wear/condition","magic/enchantment")
for(var/X in checked_vars)
//look up the 'vars' list
if(src.vars[X] != O.vars[X]) return 0
return 1 //if all those vars are equal, return 1
mob
Entered(obj/item/O)
if(istype(O)) //if what has entered is an item and not something else
var/obj/item/X = locate(O.type) in src //try to find an object of the same type already in src**
if(X && O.IsEqual(X))
X.amount += O.amount
del O
if(O) ..()
//you could also do the same on turf/Entered(), if you \
want dropped items to stack on the ground

**: For this, I've noted a possible problem on the previous thread, so just making sure you remember it.

I plan on doing a weight system later on in development really.

You can check this [link] or other posts by using the forum search for basic inspiration. I'd also look all of those up, mind. :P
EDIT: Added verbs
In response to Kaioken
Is this good so far? I get a couple errors though.

obj/proc/isEqual(obj/O)
var/list/checked_vars = list("type","name","icon")
for(var/X in checked_vars)
if(src.vars[X] != O.vars[X]) return 0
return 1

mob
Entered(obj/O)
if(istype(O))
var/obj/X = locate(O.type) in src
if(X && O.isEqual(X))
X.Amount += O.Amount //Both errors are here in this line
del(O)
if(O) ..()

#define isWhole(number) (number==round(number,1))
obj/Weaponry
density = 1
layer = MOB_LAYER
Knife
icon = 'Knife.dmi'
Price = 500
var/Material
var/Amount
Bump(atom/A)
var/mob/O = Owner
if(ismob(A))
var/mob/M = A
var/dmg = round(O.KnifeSkill + O.Taijutsu)
switch(Material)
if("Bronze") dmg*=1
if("Iron") dmg*=1.5
if("Steel") dmg*=2
M.Health -= dmg
view(M)<<"<font color=silver>[M]</font> was hit by \a <font color=silver>[src]</font> for <font color=red>[dmg]</font>"
O.KnifeEXP += M.Level
O.KnifeLvlUp()
M.Death(O)
if(istype(A,/obj/Training/Training_Log))
var/rndm = rand(20,30)
O.KnifeEXP += rndm
O.KnifeLvlUp()
O<<output("<font size=1>You gain [rndm] Experience","Crap")
spawn(50) del(src)
New()
src.name = "[src.Material] Knife"
src.suffix = "([Amount])"
..()
Bronze
Material = "Bronze"
Amount = 5
Iron
Material = "Iron"
Amount = 5
Steel
Material = "Steel"
Amount = 5
verb
Drop()
var/obj/dropped_obj = src
if(src.Amount)
var/drop = input("How many do you want to drop?\n- You have [src.Amount] [src]\s","Drop") as num
if(drop > src.Amount || !isWhole(drop) || drop <= 0) return
src.Amount -= abs(drop)
src.suffix = "([src.Amount])"
dropped_obj.Move(usr.loc)
if(!src.Amount) del(src)
if(dropped_obj.Move(usr.loc))
usr<<"You dropped [dropped_obj]\s"
usr.AutoSave()
Get()
set src in oview(1)
if(src.Move(usr))
if(src.Amount)
usr<<"Your pick up [src.Amount] [src]\s"
else
usr<<"Your pick up \a [src]"
usr.AutoSave()
Throw()
var/obj/Weaponry/Knife/X = new(usr.loc)
X.MoveDelay = 1
X.Owner = usr
walk(X,usr.dir)
src.Amount -= 1
src.suffix = "([src.Amount])"
if(!src.Amount) del(src)


Errors
World Procs.dm:120:error:O.Amount:undefined var
World Procs.dm:120:error:X.Amount:undefined var
In response to Mizukouken Ketsu
Typecasting. You typecasted those objects as of type /obj, but the problem is that /objs don't have an Amount var. Only the specific subtype of /obj/Weaponry/Knife does*.

--You're not checking if drop is 0/false.
--In Bump(), you're deleting the knife always after 5 seconds, even if it's been picked up by a player, which partly defeats the purpose.

*: Again, I'd suggest an 'item system'. Put all item types under /obj/item. Do you really only want knives stackable, pick-upable, droppable and throwable? O.o You get what I mean, anyway. >_>
In response to Kaioken
Ignoring the spawn() in the Bump()... I'm getting a runtime error whenever I try to drop some Knives.

obj/Items
Weaponry
density = 1
layer = MOB_LAYER
Knife
icon = 'Knife.dmi'
Price = 500
var/Material
Bump(atom/A)
var/mob/O = Owner
if(ismob(A))
var/mob/M = A
var/dmg = round(O.KnifeSkill + O.Taijutsu)
switch(Material)
if("Bronze") dmg*=1
if("Iron") dmg*=1.5
if("Steel") dmg*=2
M.Health -= dmg
view(M)<<"<font color=silver>[M]</font> was hit by \a <font color=silver>[src]</font> for <font color=red>[dmg]</font>"
O.KnifeEXP += M.Level
O.KnifeLvlUp()
M.Death(O)
if(istype(A,/obj/Other/Training_Log))
var/rndm = rand(20,30)
O.KnifeEXP += rndm
O.KnifeLvlUp()
O<<output("<font size=1>You gain [rndm] Experience","Crap")
spawn(50) del(src)
New()
src.name = "[src.Material] Knife"
src.suffix = "([Amount])"
..()
Bronze
Material = "Bronze"
Amount = 5
Iron
Material = "Iron"
Amount = 5
Steel
Material = "Steel"
Amount = 5
verb
Drop()
var/obj/dropped_obj = src
if(src.Amount)
var/drop = input("How many do you want to drop?\n- You have [src.Amount] [src]\s","Drop") as num
if(drop > src.Amount || !isWhole(drop) || drop <= 0) return
src.Amount -= abs(drop)
src.suffix = "([src.Amount])"
dropped_obj.Move(usr.loc)
if(!src.Amount) del(src)
if(dropped_obj.Move(usr.loc))
usr<<"You dropped [dropped_obj]\s"
usr.AutoSave()
Get()
set src in oview(1)
if(src.Move(usr))
if(src.Amount)
usr<<"Your pick up [src.Amount] [src]\s"
else
usr<<"Your pick up \a [src]"
usr.AutoSave()
Throw()
var/obj/Items/Weaponry/Knife/X = new(usr.loc)
X.MoveDelay = 1
X.Owner = usr
walk(X,usr.dir)
src.Amount -= 1
src.suffix = "([src.Amount])"
if(!src.Amount) del(src)

runtime error: Cannot read "".KnifeSkill
proc name: Bump (/obj/Items/Weaponry/Knife/Bump)
usr: Wolf (/mob)
src: Bronze Knife (/obj/Items/Weaponry/Knife/Bronze)
call stack:
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Bump(Wolf (/mob))
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Move(Floor12 (42,13,1) (/turf/Floors/Floor12))
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Drop()
runtime error: Cannot read "".KnifeSkill
proc name: Bump (/obj/Items/Weaponry/Knife/Bump)
usr: Wolf (/mob)
src: Bronze Knife (/obj/Items/Weaponry/Knife/Bronze)
call stack:
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Bump(Wolf (/mob))
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Move(Floor12 (42,13,1) (/turf/Floors/Floor12))
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Drop()
In response to Mizukouken Ketsu
Yeah, it's bumping when you drop it since it's effectively dense. You can either use a 'trick move' when dropping so it doesn't move when dropping it, or more likely, make it not dense when it's dropped, and dense when it's thrown.
In response to Kaioken
Okay I dropped 1 Knife, and the entire pile of 21 was dropped. Then when I tried to pick it up, it wasn't moved to my inventory.
In response to Mizukouken Ketsu
That's pretty obvious, it's because you're moving the original object (with X Amount) itself instead of creating a new one with the wanted amount inside the player inventory, then moving that, effectively by setting dropped_obj to it.
In response to Kaioken
I tried to understand what you wanted me to do, I really did. And I get the concept of it. I just can't think of a way to implement it :\

            verb
Drop()
var/obj/dropped_obj = src
var/obj/XYZ
if(src.Amount)
var/drop = input("How many do you want to drop?\n- You have [src.Amount] [src]\s","Drop") as num
if(drop > src.Amount || !isWhole(drop) || drop <= 0) return
src.Amount -= abs(drop)
src.suffix = "([src.Amount])"
dropped_obj = XYZ
XYZ.Amount = drop
XYZ.Move(usr.loc)
if(!src.Amount) del(src)
if(dropped_obj.Move(usr.loc))
usr<<"You dropped [dropped_obj]\s"
usr.AutoSave()
In response to Mizukouken Ketsu
For example, dropped_obj = new src.type(usr).
In response to Kaioken
Making progress :D

            verb
Drop()
var/obj/dropped_obj = src.type
if(src.Amount)
var/drop = input("How many do you want to drop?\n- You have [src.Amount] [src]\s","Drop") as num
if(drop > src.Amount || !isWhole(drop) || drop <= 0) return
src.Amount -= abs(drop)
src.suffix = "([src.Amount])"
dropped_obj.Amount = drop
dropped_obj.Move(usr.loc)
if(!src.Amount) del(src)
if(dropped_obj.Move(usr.loc))
usr<<"You dropped [dropped_obj]\s"
usr.AutoSave()


Runtime error

runtime error: Cannot modify /obj/Items/Weaponry/Knife/Bronze.Amount.
proc name: Drop (/obj/Items/Weaponry/Knife/verb/Drop)
usr: Wolf (/mob)
src: Bronze Knife (/obj/Items/Weaponry/Knife/Bronze)
call stack:
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Drop()
In response to Mizukouken Ketsu
Dropped object is a type path, so you can't move it no matter how hard you try; it isn't a real thing.
In response to Jeff8500
So how would I make it a real obj that CAN be dropped?
In response to Mizukouken Ketsu
Look up new().
In response to Jeff8500
?

            verb
Drop()
var/obj/dropped_obj = new(src.type,usr)
if(src.Amount)
var/drop = input("How many do you want to drop?\n- You have [src.Amount] [src]\s","Drop") as num
if(drop > src.Amount || !isWhole(drop) || drop <= 0) return
src.Amount -= abs(drop)
src.suffix = "([src.Amount])"
dropped_obj.Amount = drop
dropped_obj.Move(usr.loc)
if(!src.Amount) del(src)
if(dropped_obj.Move(usr.loc))
usr<<"You dropped [dropped_obj]\s"
usr.AutoSave()
In response to Mizukouken Ketsu
Think, what's the syntax of new()? new typepath(args). The first arg of new will always be it's location. There are no other args unless you define them.
In response to Jeff8500
It creates the new obj now, but it gives it its default Amount (5), and then it gives me the following runtime error.

runtime error: Cannot modify /obj/Items/Weaponry/Knife/Bronze.Amount.
proc name: Drop (/obj/Items/Weaponry/Knife/verb/Drop)
usr: Wolf (/mob)
src: Bronze Knife (/obj/Items/Weaponry/Knife/Bronze)
call stack:
Bronze Knife (/obj/Items/Weaponry/Knife/Bronze): Drop()

            verb
Drop()
var/obj/dropped_obj = src.type
if(src.Amount)
var/drop = input("How many do you want to drop?\n- You have [src.Amount] [src]\s","Drop") as num
if(drop > src.Amount || !isWhole(drop) || drop <= 0) return
src.Amount -= abs(drop)
src.suffix = "([src.Amount])"
new dropped_obj(usr)
dropped_obj.Amount = drop
dropped_obj.Move(usr.loc)
if(!src.Amount) del(src)
if(dropped_obj.Move(usr.loc))
usr<<"You dropped [dropped_obj]\s"
usr.AutoSave()
In response to Mizukouken Ketsu
Because dropped object is a type path, I thought we already covered this? :P
Page: 1 2