Waaaaagh
I lost all my rep and my title being a jerk
- Reaction score
- 70
Hey all. Just wondering, what do you want in an rpg item system?
Currently planned features for mine-
Items:
1) Bags - Done Completely!!!
2) Stacking Items - Done Completely!!!
3) Item Based Spellbooks
4) Pick Up Anytime Items - Done Completely!!!
5) Equipment System - Done Completely!!!
6) Item Encumbrance
7) Item Durability - Pending...
8) Item Based Merchant with Variable Item Costs
9) Equipment Augmentations
Heroes:
10) Max Level Skill Point Gain
11) On Level Attributer
12) Hero Alignment
If you have any suggestions for things you would like to see, I wanna hear 'em, so I can maybe implement them.
Because I want to show that this is not all just theorizing, here is my WIP code:
Currently planned features for mine-
Items:
1) Bags - Done Completely!!!
2) Stacking Items - Done Completely!!!
3) Item Based Spellbooks
4) Pick Up Anytime Items - Done Completely!!!
5) Equipment System - Done Completely!!!
6) Item Encumbrance
7) Item Durability - Pending...
8) Item Based Merchant with Variable Item Costs
9) Equipment Augmentations
Heroes:
10) Max Level Skill Point Gain
11) On Level Attributer
12) Hero Alignment
If you have any suggestions for things you would like to see, I wanna hear 'em, so I can maybe implement them.
Because I want to show that this is not all just theorizing, here is my WIP code:
JASS:
scope WMI
globals
private constant integer Nextpage = 039;I002039;
private constant integer Cancel = 039;I001039;
private constant integer Blank = 039;I003039;
endglobals
private function H2I takes handle h returns integer
return h
return 0
endfunction
globals
private sound aSimError
endglobals
private function SimError takes player p, string msg returns nothing
if(aSimError==null)then
set aSimError=CreateSoundFromLabel( "InterfaceError",false,false,false,10,10)
call StartSound(aSimError)
endif
if(GetLocalPlayer()==p)then
call ClearTextMessages()
call DisplayTimedTextToPlayer(p,0.52,-1.00,2.00,"|cffffcc00"+msg+"|r")
call StartSound(aSimError)
endif
endfunction
private function UnitGetItemSlot takes unit u,item i returns integer
local integer a=0
loop
exitwhen a>5
if(i==UnitItemInSlot(u,a))then //Found it
return a
endif
set a=a+1
endloop
return -1 //Not found
endfunction
//! runtextmacro HASHTABLE("Mitems","private")
//! runtextmacro HASHTABLE("PUAs","private")
//! runtextmacro HASHTABLE("A","private")
struct pitem
//The pitem is basically an improved version of the item.
//It contains information about the item, as well as a
//group of methods for enhancing the functionality of the
//pitem. There are two purposes for the pitem in WMI:
//1) It is passed through methods as its own type
//2) It allows an item to be picked up at any time, even
//if inventory is full.
item main
item PUA
integer PUAid
method getmain takes nothing returns item
return .main
endmethod
method getPUA takes nothing returns item
return .PUA
endmethod
static method is takes item i returns boolean
local real l=GetWidgetLife(i)
if(l==74.)then //It's a main.
return HashtableMitems.containsKey(H2I(i))
elseif(l==73.)then //PUA!!!!!
return HashtablePUAs.containsKey(H2I(i))
endif
return false
endmethod
static method get takes item i returns pitem
local real l=GetWidgetLife(i)
if(l==74.)then //It's a main.
return HashtableMitems.get(H2I(i))
elseif(l==73.)then //PUA!!!!!
return HashtablePUAs.get(H2I(i))
endif
return 0
endmethod
static method TryStack takes hero h, pitem p returns boolean
local integer a=0
local item temp
local integer id=GetItemTypeId(p.main)
local integer max=GetItemLevel(p.main)
local integer charges
local integer tempcharges
loop
exitwhen a>5
set temp=UnitItemInSlot(h.hero,a)
if(GetItemTypeId(temp)==id)then //Matching types
set charges=GetItemCharges(p.main)
set tempcharges=GetItemCharges(temp)
if(tempcharges+charges>max)then //Too many!
if(tempcharges==max)then //Full
else //Add remainder
set tempcharges=max-tempcharges //The number left to add
call SetItemCharges(p.main,charges-tempcharges)
call SetItemCharges(temp,max)
endif
else //Just add them all
call SetItemCharges(temp,tempcharges+charges)
call p.destroy()
return true
endif
endif
set a=a+1
endloop
return false
endmethod
static method TryAdd takes hero h, pitem p returns boolean
local integer a=0
local item temp
local integer state=h.state
set h.state=-1
if(state==0)then //MAIN!!!
call SetItemVisible(p.main,true)
if(not UnitAddItem(h.hero,p.main))then //Needs to be hidden again
call SetItemVisible(p.main,false)
else
call TriggerSleepAction(0)
set h.state=state
return true
endif
elseif(state==1)then //BAG!!!
loop
exitwhen a>3
set temp=UnitItemInSlot(h.hero,a)
if(GetItemTypeId(temp)==Blank)then //It's a blank
call UnitRemoveItem(h.hero,temp)
call RemoveItem(temp)
call SetItemVisible(p.main,true)
call UnitAddItem(h.hero,p.main)
call TriggerSleepAction(0)
set h.state=state
return true
endif
set a=a+1
endloop
endif
set h.state=state
return false
endmethod
static method TryBag takes hero h, pitem p returns boolean
local bag b=h.openbag
return b.addpitem(p)
endmethod
static method TryMain takes hero h, pitem p returns boolean
local integer a=1
local integer id=GetItemTypeId(p.main)
local integer max=GetItemLevel(p.main)
local integer charges
local integer tempcharges
loop
exitwhen a>6
if(GetItemTypeId(h.pitems[a].main)==id)then //Matching types
set charges=GetItemCharges(p.main)
set tempcharges=GetItemCharges(h.pitems[a].main)
if(tempcharges+charges>max)then //Too many!
if(tempcharges==max)then //Full
else //Add remainder
set tempcharges=max-tempcharges //The number left to add
call SetItemCharges(p.main,charges-tempcharges)
call SetItemCharges(h.pitems[a].main,max)
endif
else //Just add them all
call SetItemCharges(h.pitems[a].main,tempcharges+charges)
call p.destroy()
return true
endif
endif
set a=a+1
endloop
set a=1
loop
exitwhen a>6
if(h.pitems[a]==0)then //It's empty
set h.pitems[a]=p
endif
set a=a+1
endloop
return false
endmethod
static method TryBags takes hero h, pitem p returns boolean
local integer a=1
loop
exitwhen a>6
if(bag.is(h.pitems[a]) and bag.get(h.pitems[a]).addpitem(p))then //It was added to the bag!
return true
endif
set a=a+1
endloop
return false
endmethod
static method Pickup takes nothing returns nothing
local pitem p=pitem.get(GetManipulatedItem())
local hero h=HashtableA.get(H2I(GetTriggeringTrigger()))
local real x
local real y
if(GetManipulatedItem()==p.PUA)then //A PUA was picked
set x=GetItemX(p.PUA)
set y=GetItemY(p.PUA)
call HashtablePUAs.remove(H2I(p.PUA))
set p.PUA=CreateItem(p.PUAid,x,y)
call SetWidgetLife(p.PUA,73.)
call SetItemInvulnerable(p.PUA,true)
call SetItemVisible(p.PUA,false)
if(not pitem.TryStack(h,p))then //Try again
if(not pitem.TryAdd(h,p))then //Try again
if(h.state==1 and not pitem.TryBag(h,p))then //Try once more
if(h.state>1 and not pitem.TryMain(h,p))then //One more time
if(h.state>1 and not pitem.TryBags(h,p))then //FAILURE.
call SetItemVisible(p.PUA,true) //Make the PUA visible again.
endif //Lines up nice xD
endif //Lines up nice xD
endif //Lines up nice xD <---- PUA Comments Here
endif //Lines up nice xD
endif //Lines up nice xD
elseif(GetManipulatedItem()==p.main and h.state==0)then //MAIN AHOY!!!
set h.pitems[UnitGetItemSlot(h.hero,p.main)+1]=p
endif
endmethod
static method Drop takes nothing returns nothing
local pitem p=pitem.get(GetManipulatedItem())
local hero h=HashtableA.get(H2I(GetTriggeringTrigger()))
local real x
local real y
if(h.state==0 and GetManipulatedItem()==p.main)then //He dropped a main from main!
call TriggerSleepAction(0)
set x=GetItemX(p.main)
set y=GetItemY(p.main)
call SetItemVisible(p.main,false)
call SetItemVisible(p.PUA,true)
call SetItemPosition(p.PUA,x,y)
endif
endmethod
static method create takes integer id, integer puaid, real x, real y returns pitem
local pitem p=pitem.allocate()
set p.main=CreateItem(id,0.,0.)
call SetWidgetLife(p.main,74.)
call SetItemInvulnerable(p.main,true)
call SetItemVisible(p.main,false)
call HashtableMitems.put(H2I(p.main),p)
set p.PUA=CreateItem(puaid,x,y)
set p.PUAid=puaid
call SetWidgetLife(p.PUA,73.)
call SetItemInvulnerable(p.PUA,true)
call SetItemVisible(p.PUA,false)
call HashtablePUAs.put(H2I(p.PUA),p)
return p
endmethod
method onDestroy takes nothing returns nothing
call HashtableMitems.remove(H2I(.main))
call HashtablePUAs.remove(H2I(.PUA))
call RemoveItem(.main)
call RemoveItem(.PUA)
endmethod
endstruct
struct hero
//The hero is the frame upon which WMI is built.
//Only heroes can access the advanced features
//of the system, and creating one is as simple
//as creating a unit. Just call:
//
//hero.create(player p,integer id, real x, real y, real facing)
//
//to create a hero with full WMI enhancement.
unit hero
player owner
integer state //0=main 1=bag 2=book 3=shop
integer maxlevel
integer fakemaxlevel
integer fakelevel
trigger pickup
trigger use
trigger order
trigger drop
trigger levelup
item nextpage
item cancel
bag openbag
//book openbook
//shop openshop
pitem array pitems[6]
method clearinv takes nothing returns nothing
local integer a=0
local item temp
local integer state=.state
set .state=-1
if(state==0)then //MAIN
loop
exitwhen a==.pitems.size
set temp=UnitItemInSlot(.hero,a)
if(GetItemTypeId(temp)==Blank)then
set .pitems[a]=0
call RemoveItem(temp)
else
set .pitems[a]=pitem.get(temp)
call UnitRemoveItem(.hero,temp)
call SetItemVisible(temp,false)
endif
set a=a+1
endloop
elseif(state==1)then //BAG
loop
exitwhen a==.pitems.size
set temp=UnitItemInSlot(.hero,a)
if(GetItemTypeId(temp)==Blank)then
set .openbag.pitems[(.openbag.currentpage-1)*4+a]=0
call RemoveItem(temp)
else
if(a<5)then
set .openbag.pitems[(.openbag.currentpage-1)*4+a]=pitem.get(temp)
endif
call UnitRemoveItem(.hero,temp)
call SetItemVisible(temp,false)
endif
set a=a+1
endloop
elseif(state>1)then //OTHERS
loop
exitwhen a==.pitems.size
set temp=UnitItemInSlot(.hero,a)
if(GetItemTypeId(temp)==Blank)then
call RemoveItem(temp)
else
call UnitRemoveItem(.hero,temp)
call SetItemVisible(temp,false)
endif
set a=a+1
endloop
endif
call TriggerSleepAction(0)
set .state=state
endmethod
method restoreinv takes nothing returns nothing
local integer a=0
set .state=-1
loop
exitwhen a==.pitems.size
call SetItemVisible(.pitems[a].main,true)
call UnitAddItem(.hero,.pitems[a].main)
set a=a+1
endloop
call TriggerSleepAction(0)
set .state=0
endmethod
method setmaxlevel takes integer level, integer fakelevel returns nothing
if(level>99)then
set level=99
elseif(level<1)then
set level=1
endif
if(fakelevel<1)then
set fakelevel=1
endif
if(GetHeroLevel(.hero)>level)then
call SetHeroLevel(.hero,level,true)
endif
set .maxlevel=level
if(fakelevel<.fakelevel)then
set .fakelevel=fakelevel
endif
set .fakemaxlevel=fakelevel
endmethod
static method LevelUp takes nothing returns nothing
local hero h=HashtableA.get(H2I(GetTriggeringTrigger()))
local integer level=GetHeroLevel(h.hero)
if(level>h.maxlevel)then //Gonna need to set that back down
call SetHeroLevel(h.hero,h.maxlevel,false)
set h.fakelevel=h.fakelevel+1
if(h.fakelevel>h.fakemaxlevel)then //No points for you. Sorry.
set h.fakelevel=h.fakemaxlevel
else //Add some skill points.
call UnitModifySkillPoints(h.hero,1)
endif
endif
endmethod
static method create takes player p, integer id, real x, real y, real face returns hero
local hero h=hero.allocate()
set h.hero=CreateUnit(p,id,x,y,face)
set h.owner=p
set h.state=0
set h.maxlevel=10
set h.fakemaxlevel=10
set h.fakelevel=1
set h.pickup=CreateTrigger()
set h.use=CreateTrigger()
set h.order=CreateTrigger()
set h.drop=CreateTrigger()
set h.levelup=CreateTrigger()
call HashtableA.put(H2I(h.pickup),h)
call HashtableA.put(H2I(h.use),h)
call HashtableA.put(H2I(h.order),h)
call HashtableA.put(H2I(h.drop),h)
call HashtableA.put(H2I(h.levelup),h)
call TriggerRegisterUnitEvent(h.pickup,h.hero,EVENT_UNIT_PICKUP_ITEM)
call TriggerRegisterUnitEvent(h.use,h.hero,EVENT_UNIT_USE_ITEM)
call TriggerRegisterUnitEvent(h.order,h.hero,EVENT_UNIT_ISSUED_TARGET_ORDER)
call TriggerRegisterUnitEvent(h.drop,h.hero,EVENT_UNIT_DROP_ITEM)
call TriggerRegisterUnitEvent(h.levelup,h.hero,EVENT_UNIT_HERO_LEVEL)
call TriggerAddAction(h.pickup,function pitem.Pickup)
call TriggerAddAction(h.pickup,function bag.Pickup)
call TriggerAddAction(h.use,function bag.Use)
call TriggerAddAction(h.order,function bag.Order)
call TriggerAddAction(h.drop,function pitem.Drop)
call TriggerAddAction(h.levelup,function hero.LevelUp)
set h.nextpage=CreateItem(Nextpage,0,0)
set h.cancel=CreateItem(Cancel,0,0)
set h.openbag=0
return h
endmethod
endstruct
//! runtextmacro HASHTABLE("Bags","private")
//! runtextmacro HASHTABLE("BagUse","private")
//! runtextmacro HASHTABLE("BagOrder","private")
struct bag
pitem bag
pitem array pitems[20]
integer index
integer currentpage
triggeraction use
triggeraction order
hero owner
static method is takes pitem p returns boolean
return HashtableBags.containsKey(H2I(p.main))
endmethod
static method get takes pitem p returns bag
return HashtableBags.get(H2I(p.main))
endmethod
static method Pickup takes nothing returns nothing
local hero h=HashtableA.get(H2I(GetTriggeringTrigger()))
local pitem p=pitem.get(GetManipulatedItem())
if(bag.is(p))then
set bag.get(p).owner=h
endif
endmethod
static method Use takes nothing returns nothing //Actions for when a hero uses an item.
local hero h=HashtableA.get(H2I(GetTriggeringTrigger())) //Get the hero from the trigger
local item it=GetManipulatedItem()
local pitem p
local bag b
if(h.state==1 and it==h.nextpage)then //Nextpage button
call h.clearinv()
call h.openbag.nextpage()
elseif(h.state==1 and it==h.cancel)then //Cancel the bag
call h.clearinv()
call h.restoreinv()
else
set p=pitem.get(it)
if(bag.is(p))then //A bag was used
set b=bag.get(p)
call h.clearinv()
call b.showpage(b.currentpage)
endif
endif
endmethod
static method Order takes nothing returns nothing //Actions for when a hero issued an order.
local hero h=HashtableA.get(H2I(GetTriggeringTrigger()))
local bag b
local integer order=GetIssuedOrderId()
local integer dropslot=order-852002
local pitem dragged=pitem.get(GetOrderTargetItem())
local pitem dropped=pitem.get(UnitItemInSlot(h.hero,dropslot))
local integer dragslot=UnitGetItemSlot(h.hero,dragged.main)
local integer state=h.state
set h.state=-1
if(state==0 or order<852002 or order>852007)then
return
endif
if(bag.is(dragged) and state==0)then //Add it to the bag.
set b=bag.get(dragged)
if(not b.addpitem(dropped))then
call SimError(h.owner,"That bag is full.")
else
call UnitRemoveItem(h.hero,dropped.main)
call SetItemVisible(dropped.main,false)
call SetItemCharges(b.bag.main,b.index)
endif
call UnitDropItemSlot(h.hero,dragged.main,dropslot)
elseif(dragged.main==h.cancel and state==1)then
set b=h.openbag
if(dragged.main!=dropped.main)then //We needs to be dropping that item out.
set dropped=b.removepitem((b.currentpage-1)*4+dragslot)
if(UnitDropItemSlot(h.hero,dragged.main,dropslot))then
call UnitAddItemById(h.hero,Blank)
endif
else //Double Cancel Drop. Go to last page.
call h.clearinv()
call b.showpage(100) //Should max out the page. If not, you're crazy.
endif
elseif(dragged.main==h.nextpage and state==1)then
set b=h.openbag
if(dragged.main!=dropped.main)then //It was dropped on nextpage. WTF do we do?
if(b.readdpitem(dropped))then //This should always work
call UnitDropItemSlot(h.hero,dragged.main,dropslot)
call h.clearinv()
call b.showpage(b.currentpage)
else
call BJDebugMsg("ReAdd Failure")
endif
else //I delcare a double nextpage drop!!! Go to first page.
call h.clearinv()
call b.showpage(-1) //Should get the first page
endif
endif
endmethod
static method create takes integer id, integer puaid, real x, real y returns bag
local bag b=bag.allocate()
set b.bag=pitem.create(id,puaid,x,y)
call HashtableBags.put(H2I(b.bag.main),b)
set b.index=0
return b
endmethod
method addpitem takes pitem p returns boolean
local integer a=0
local integer id=GetItemTypeId(p.main)
local integer max=GetItemLevel(p.main)
local integer charges
local integer tempcharges
set .index=.index+1
loop //Check for pre-existing pitem.
exitwhen a>.index
if(.pitems[a]==p)then //Already there, bitch!
if(.index>=.pitems.size)then
set .index=.pitems.size-1
endif
return false
endif
set a=a+1
endloop
set a=1
loop
exitwhen a>.index
if(GetItemTypeId(.pitems[a].main)==id)then //Same type
set charges=GetItemCharges(p.main)
set tempcharges=GetItemCharges(.pitems[a].main)
if(tempcharges+charges>max)then //Too many!
if(tempcharges==max)then //Full
else //Add remainder
set tempcharges=max-tempcharges //The number left to add
call SetItemCharges(p.main,charges-tempcharges)
call SetItemCharges(.pitems[a].main,max)
endif
else //Just add them all
call SetItemCharges(.pitems[a].main,tempcharges+charges)
call p.destroy()
if(.index>=.pitems.size)then
set .index=.pitems.size-1
endif
return true
endif
endif
set a=a+1
endloop
if(.index>=.pitems.size)then
set .index=.pitems.size-1
return false
endif
//Made it past all the shit. Just add the pitem!
set .pitems[.index]=p
return true
endmethod
method removepitem takes integer index returns pitem
local pitem p=.pitems[index]
local integer a=0
local integer id=GetItemTypeId(p.main)
local integer max=GetItemLevel(p.main)
local integer charges
local integer tempcharges
if(.index>.pitems.size-1)then
set .index=.pitems.size-1
endif
loop
exitwhen index==.pitems.size
if(index<.pitems.size-1)then
set .pitems[index]=.pitems[index+1]
else
set .pitems[.pitems.size-1]=0
endif
set index=index+1
endloop
set .index=.index-1
loop
exitwhen a==.owner.pitems.size
if(GetItemTypeId(.pitems[a].main)==id)then //Same type
set charges=GetItemCharges(p.main)
set tempcharges=GetItemCharges(.owner.pitems[a].main)
if(tempcharges+charges>max)then //Too many!
if(tempcharges==max)then //Full
else //Add remainder
set tempcharges=max-tempcharges //The number left to add
call SetItemCharges(p.main,charges-tempcharges)
call SetItemCharges(.owner.pitems[a].main,max)
endif
else //Just add them all
call SetItemCharges(.owner.pitems[a].main,tempcharges+charges)
call p.destroy()
return 0
endif
endif
set a=a+1
endloop
set a=0
loop
exitwhen a==.owner.pitems.size
if(.owner.pitems[a]==0)then //Blank. Add it.
set .owner.pitems[a]=p
call UnitRemoveItem(.owner.hero,p.main)
call SetItemVisible(p.main,false)
return p
endif
set a=a+1
endloop
call UnitRemoveItem(.owner.hero,p.main)
call SetItemVisible(p.main,false)
call SetItemVisible(p.PUA,true)
call SetItemPosition(p.PUA,GetUnitX(.owner.hero),GetUnitY(.owner.hero))
call SimError(.owner.owner,"No room left in inventory.")
return p
endmethod
method readdpitem takes pitem p returns boolean
local integer a=0
local boolean bool=false
loop
exitwhen a==.pitems.size
if(.pitems[a]==p)then //Found it.
set bool=true
endif
if(bool)then
if(a<.pitems.size-1)then //Set it to the one above
set .pitems[a]=.pitems[a+1]
else //Null it
set .pitems[a]=0
endif
endif
set a=a+1
endloop
if(bool)then
return .addpitem(p)
endif
return false
endmethod
method showpage takes integer page returns nothing
local hero h=.owner
local integer a=0
if(h==0)then
return
endif
if(page>5)then
set page=5
elseif(page<1)then
set page=1
endif
set h.state=-1
set .currentpage=page
set page=(page-1)*4
loop
exitwhen a>3
if(.pitems[page+a]==0)then //It's blank
call UnitAddItemById(h.hero,Blank)
else //pitem is there, so show it!
call UnitAddItem(h.hero,.pitems[page+a].main)
endif
set a=a+1
endloop
call UnitAddItem(h.hero,h.nextpage)
call SetItemCharges(h.nextpage,.currentpage)
call UnitAddItem(h.hero,h.cancel)
call SetItemCharges(h.nextpage,5)
call TriggerSleepAction(0)
set h.state=1
endmethod
method nextpage takes nothing returns nothing
if(.currentpage<5)then
call .showpage(.currentpage+1)
else
call .showpage(1)
endif
endmethod
endstruct
//===========================================================================
public function InitTrig takes nothing returns nothing
endfunction
endscope