ID:775364
 
(See the best response by LordAndrew.)
Code:
turf
Grass
icon='Turf.dmi';icon_state="Grass"

Click()
var/obj/A=new/obj/
if(usr.Selected=="Nothing") {A:Upgrade();return}
if(usr.Selected=="Turret")
if(usr.Cash<A.BuyPrice) {usr<<"You don't have enough cash.";return}
usr.Cash-=A.BuyPrice
new/obj/Turret(src)


Problem description:
It's not calling A:Upgrade() also, whenever I have it A.Upgrade() I get an error saying it's an undefined proc.
Could you post the code for how you're defining Upgrade()?
obj/Turret
icon='Turret.dmi';icon_state="Turret"
New()
src.Owner=usr
src.Shoot()

proc/Shoot()
while(src)
new/obj/Bullet(src)
sleep(src.FireRate)

verb/Info()
set src in oview(20);set category=null
alert("Sell Price: [src.SellPrice]\nRange: [src.Range]/8\nFire Rate: [src.FireRate]/4")

verb/Sell()
set src in oview(20);set category=null
switch(alert(usr,"Are you sure you want to sell this Turret for $[src.SellPrice]?","Selling","Yes","Cancel"))
if("Yes")
usr<<"You sold the Turret"
usr.Cash+=src.SellPrice
for(var/obj/Bullet/M in world)
if(M.Owner==src) del(M)
del(src)

proc/Upgrade()
set src in oview(20);set category=null
var/RangeCost=35
var/DamageCost=40
var/FireRateCost=30
switch(input(usr,"What would you like to upgrade?","Upgrade Selection")in list("Range","Damage","Fire Rate"))
if("Range")
if(src.Range>=8) {usr<<"This upgrade is already at the maximum.";return}
switch(alert(usr,"Range allows the Turret to shoot an extra distance\nCost: [(RangeCost)*(src.Range)]\nCurrent Level: [src.Range]/8","Information","Buy","Cancel"))
if("Buy")
if(!(usr.Cash>=RangeCost*src.Range)) {usr<<"Not enough cash!";return}
usr.Cash-=RangeCost*src.Range;src.Range+=1
usr<<"You've upgrade this Turrets Range to [src.Range]"
src.SellPrice+=(RangeCost*src.Range)/2;return
if("Damage")
if(src.Damage>=4) {usr<<"This upgrade is already at the maximum.";return}
switch(alert(usr,"Damage allows the Turret to damage enemies even more\nCost: [(DamageCost)*(src.Damage)]\nCurrent Level: [src.Damage]/4","Information","Buy","Cancel"))
if("Buy")
if(!(usr.Cash>=DamageCost*src.Damage)) {usr<<"Not enough cash!";return}
usr.Cash-=DamageCost*src.Damage;src.Damage+=1
usr<<"You've upgrade this Turrets Damage to [src.Damage]"
src.SellPrice+=(DamageCost*src.Damage)/2;return
if("Fire Rate")
if(src.FireRate<=0) {usr<<"This upgrade is already at the maximum.";return}
switch(alert(usr,"Fire Rate allows the Turret to shoot more faster\nCost: [(FireRateCost)*(src.FireRate)]\nCurrent Level: [src.FireRate]/4","Information","Buy","Cancel"))
if("Buy")
if(!(usr.Cash>=FireRateCost*src.FireRate)) {usr<<"Not enough cash!";return}
usr.Cash-=FireRateCost*src.FireRate;src.FireRate-=1
usr<<"You've upgrade this Turrets FireRate to [src.FireRate]"
src.SellPrice+=(FireRateCost*src.FireRate)/2;return


Didn't know if you wanted the whole code or not.
Best response
There's a number of design flaws present in your stuff here, a few of which pertain to why your Upgrade() proc isn't working.

The : operator (also known as the lax operator) is a rather dangerous thing to use, as it can lead to disaster and runtimes.

Let's look at how you're using it:
var/obj/A=new/obj/
if(usr.Selected=="Nothing") {A:Upgrade();return}


You're creating a new /obj and then calling A:Upgrade() on it. You mentioned doing A.Upgrade() tells you that the procedure is undefined, which it is. Upgrade() is defined under /obj/Turret, so the procedure would only be called if you properly typecasted specifically for turrets.

The reason A:Upgrade() doesn't work is because the lax operator ignores typecasting and attempts to access things regardless of whether or not it can truly call that variable or procedure. Because you have no Upgrade() procedure defined for the top level of /obj, it just throws out an error.

Looking at your code, you make use of usr in many places that it's just not safe at all to use it in, which results in unwanted behaviour. (More on that can be read here). In most cases, you'd want to be passing a mob as an argument in place of usr, so that we consistently know who is calling what.

// This is a really basic idea of how to do this.

obj
turret
var
tmp/mob/owner

New(mob/m)
owner = m

spawn shoot()

Click(location, control, params)
// Check to see if the user clicking this is the owner. If not, just ignore them.
if(usr != owner) return

upgrade(usr)

proc
// Create a new procedure to handle upgrading. Accept a mob as an argument for calculating costs and stuff.
upgrade(mob/m)
if(m != owner) return

// Do upgrade stuffs here.

shoot()
while(src)
// Handle the shoot routine.

// Change this to whatever suits your needs.
sleep(1)
thanks. ++