Sign in to follow this  
tbone

Brainstorming-Item Cooldown

Recommended Posts

Hey guys, this topic is for brainstorming ideas for whitefang/farjat to implement item cooldowns.

 

I was thinking of

 

1) creating an array of activatable weapons, with a time attribute. Everytime an activable item is dropped, it is added into this array.

 

If [activatable_items]->last_activate <= 20mins

{

display_msg("item not cooled down yet")

}

 

2) rewriting the item configs to add the time attribute.

 

 

Share this post


Link to post
Share on other sites

u can check it, by puttin sumthing rare ( act sh1t ) and off again, so they ll tell u how many time left u needed to use it ...

Share this post


Link to post
Share on other sites

If you're using MSSQL server it's fairly easy implement this part in the code:

 

- Add one new column to your DB (sCooldown) as smallint (not nullable)

- Bind it in the dbclasses to your record set

- Change ALL your item packets to send this value too (send as integer) -> this is cake in nemesis, we changed our packet code to actually have all such packets grouped into one single method, changing one thing changes it for ALL ;) <- this is HELL of a work when you don't have it in one method. If using fairly old sources, you'll be required to edit over 20 packets to get this done. Don't forget you also need to get the sCooldown value added for your BANK items so items don't get "reset" in cooldown when putting them in WH and taking them out !

- Add an additional check upon activation of an item that validates the item's cooldown time

- In the game-loop (where shutup time etc is decreased) add a piece of code that decreases item's cooldown time

 

This makes char & item cooldown exist next to eachother, basically the currently used config value for cooldown can be put to the sCooldown value instead of to the chars activation cooldown time.

Then make a new global definition to define the character's cooldown time. (this is kinda optional, could use the cooldown value of the item as a char cooldown too)

Share this post


Link to post
Share on other sites

White, thx for sharing ur 1337 coding opinions. Im basing on old srcs, no experience with sql servers. Where in the old srcs do i find these packets which are sent?

Share this post


Link to post
Share on other sites

White, thx for sharing ur 1337 coding opinions. Im basing on old srcs, no experience with sql servers. Where in the old srcs do i find these packets which are sent?

 

In old src you'll probably have to add another piece to the .txt file to be saved.

 

you'll probably find this somewhere in your code:


strcat(pData, "character-item = ");
memset(cTmp, ' ', 21);
strcpy(cTmp, m_pClientList[iClientH]->m_pItemList[i]->m_cName);
cTmp[strlen(m_pClientList[iClientH]->m_pItemList[i]->m_cName)] = (char)' ';
cTmp[20] = NULL;
strcat(pData, cTmp);
strcat(pData, " ");
itoa( m_pClientList[iClientH]->m_pItemList[i]->m_dwCount, cTxt, 10);
strcat(pData, cTxt);
strcat(pData, " ");

 

It's the part where it writes the item info to the txt file.

In the end you'll find:


strcat(pData, " ");
itoa( m_pClientList[iClientH]->m_pItemList[i]->m_dwAttribute, cTxt, 10);
strcat(pData, cTxt);
strcat(pData, "\n");

 

You'll probably want to extend it with the iCooldown value simeliar way:


strcat(pData, " ");
itoa( m_pClientList[iClientH]->m_pItemList[i]->m_dwAttribute, cTxt, 10);
strcat(pData, cTxt);
strcat(pData, " ");
itoa( m_pClientList[iClientH]->m_pItemList[i]->m_iCooldown, cTxt, 10);
strcat(pData, cTxt);
strcat(pData, "\n");

 

Or you could just place it inbetween some of the existing values, just depend on how you'd like to get it done, in which order you'd like the values to be saved.

 

For the packet part, the best way to find most/all packets related to items is searching for "dwAttribute" as both bank and bag items have that value to be saved.

you'll porbably find pieces of code simeliar to this one:


dwp = (DWORD *)cp;
*dwp = pItem->m_dwAttribute;
cp += 4;

 

or:

 


dwp = (DWORD *)cp;
*dwp = m_pClientList[iClientH]->m_pItemList[i]->m_dwAttribute;
cp += 4;

 

Same as with the saving part, you'll need to extend it so the value is being sent:


dwp = (DWORD *)cp;
*dwp = m_pClientList[iClientH]->m_pItemList[i]->m_dwAttribute;
cp += 4;


ip = (int *)cp;
*ip = m_pClientList[iClientH]->m_pItemList[i]->m_iCooldown;
cp += 4;

 

this you'll probably have to apply to each and every packet sent from game server to client. If you're using MSSQL server, you'll also need to get this done for game server to world server (where char files are being saved).

 

Note: be EXTREEMLY carefull on changing packets in old server code, besides changing what you send, adding values/removing values you'd also have to take in mind the amount of bytes sent from one side to another. These old pieces of code use pointers to their full potentional, if you don't have experience in using pointers or doing packet stuff, I'd advice you not to attemp this change in your code as both can have extreemly high concequences on an existing and running server such as data loss, data corruption, memory corruption, machine corruption, crashes and probably much more unwanted behavior.

Share this post


Link to post
Share on other sites

Im going off topic, but for hp bars, its these same area of codes that send other ppl's hp to be displayed on ur screen?

 

Also, white, can you explain to me what the code below means? im still trying to get the hp display up and running. just numbers first. I mean if I move my mouse over anything, be it player or mobs, it will show the name, guild (if applicable), city, and current hp.

 

sp = (short *)cp;

*sp = m_pClientList[wObjectID]->m_sType;

cp += 2;

 

based on my research (forgive me, i am noob) these are pointers. please explain how do i get other ppl hp to show in client side. thx.

Edited by tbone

Share this post


Link to post
Share on other sites

Your piece of code:


sp = (short *)cp;
*sp = m_pClientList[wObjectID]->m_sType;
cp += 2;

 

explained line by line:

 


sp = (short *)cp;

This line casts the cp (char-pointer) to an sp (short-pointer) where (short *) is the cast type, short is the type of variable, the * (astrix) indicates you want a pointer.

 


*sp = m_pClientList[wObjectID]->m_sType;

As the sp (short-pointer) points to a slot in the memory and we want to assign a value to is, we'll have to assign the value to the object, therefore we use *sp to dereffer the pointing value back to an object to finally assign the value of m_sType to this pointer.

Basically the cp is used to build up a packet as it pointer a piece of data (mostly cData) and we're adding values to the packet to be sent to another instance (client, world server, ...).

 


cp += 2;

This moves the char-pointer 2 steps ahead of its previous value. As we've just assigned a short, 2 steps are required to get to the next "blank" space which is ready to be written.

The amount of steps (bytes) you're moving forward depends on the type you've just written.

char goes by 1 byte

short and WORD goes by 2 bytes

int goes by 4 bytes

DWORD should go by 8 bytes, but in helbreath it only goes by 4 bytes and data is TRUNCATED here.

long goes by 8 bytes

char-array (e.g. char cTxt[100]) goes by the length of it's array, can be fixed value (100 for the example) of can be calculated dynamically with strlen(cTxt) for dynamic length or to ensure a fixed length could use sizeof(cTxt)

booleans are converted to char's and only take up 1 byte of data.

 

Choosing to increase the amount of bytes by the wrong value can lead to data corruption, over-reading/writing the data array etc etc, packets are fairly dangerous to use if you don't have experience or knowledge with them and/or c++ pointers.

 

for nemesis I wrote a single class that does all this kinda stuff for me, I easly make packets myself like this without having to worry about the pointers, the memory, corrupted in reading/writing or the data array size.

class CPacket * pPacket = new CPacket();
pPacket->WriteCharArray(m_pClientList[iClientH]->m_cMapName, 10);
pPacket->WriteShort(m_pClientList[iClientH]->m_sX);
pPacket->WriteShort(m_pClientList[iClientH]->m_sY);
pPacket->WriteInteger(m_pClientList[iClientH]->m_iCotnributionPoints);
if (!pPacket->SendPacket(m_pClientList[iClientH]->m_pXSock)) {

DeleteClient(iClientH);

}

 

 

 

this kinda of packet composing trough a single class that handles all the memory stuff is fairly easy to do, and makes code size 4 times smaller then before.

Where in original HB code sending 1 data value (short, int, ...) takes up to 4 lines, it only takes 1 in nemesis code due to this special class I wrote.

 

Visa-Versa I obviously also have a read method where I can simply do things like:

m_iX = pPacket->iReadInteger();

 

In this packet-class I also wrote code which makes item packets located in 1 method, I just call a WriteItem() method and pass on the item-pointer as a parameter.

So whenever I feel like changing the item packet, I only have to do it in 1 place, in this Packet-class, instead of having to look for all pieces of code.

 

P.S. An excellent article to read about pointers:

http://www.cplusplus.com/doc/tutorial/pointers/

Share this post


Link to post
Share on other sites

wow thx for detailed explanation. however, how does the client read this? if I were to send other objects' hp for viewing in client, would this be sufficient?

sp = (int *)cp;*sp = m_pClientList[wObjectID]->m_iHP;cp += 4;

Share this post


Link to post
Share on other sites

wow thx for detailed explanation. however, how does the client read this? if I were to send other objects' hp for viewing in client, would this be sufficient?

sp = (int *)cp;*sp = m_pClientList[wObjectID]->m_iHP;cp += 4;

 

You should not use the sp (short-pointer) for it.

If you lookup the declaration of the sp, it'll look like this:

short * sp;

 

As HP is an integer (int), you'll need an int-pointer (ip).

If it's not declared, declare it at the same place (top of the method) where the sp is declared:

int * ip;

 

Then in your piece of code, replace the sp with ip and it'll look like this:

ip = (int *)cp; *ip = m_pClientList[wObjectID])>m_iHP; cp += 4;

 

This concludes just the sending part from the game server to the client.

The only thing you'd still have to do is increase the number of bytes sent when this packet is finally send to the client.

Mostly the sending part in old code looks kinda like this:

iRet = m_pClientList[iClientH]->m_pXSock->SendMsg(cData, 100); // the 100 here is the amount of bytes sent, if you add an integer (4 bytes) you must increase this value by 4.

 

Now you also need to do the other way around, and lookup where that specific packet is being read/received in the client (in the LogEventHandler method).

you'll probably need to make a new variable to store the HP of your "objects" (player/npc):

int iHP;

 

then just perform the opposite of the writing to read it:

ip = (int *)cp; // This part is identical !
iHP = *ip;
cp += 4; // This part is also identical !

 

Then somewhat below it, you'll need to edit the m_pMapData->bSetOwner method so you can also store the iHP value.

This will probably also invlove you'd have to change other packets that make use of the bSetOwner method aswell as all other methods/pieces of code that use the bGetOwner method so you can also read the HP value.

 

I'd like to note that even though the packets seem so simple if I explain you as you can mostly copy-paste my exact pieces of code, the code adjustments that need to be made to store just 1 more value shouldn't be underestimated, it can take a couple days to get everything covered and working again, yet you'd still have to TEST everything again to ensure it works properly as expected.

Share this post


Link to post
Share on other sites

White do you know of:

 

1) stable srcs to work with (no sql pls)

2) free compilers for solution files

 

Thx!

 

1. I don't know, most people use helbreath X sources, mostly are stable, but have some minor bugs or incompletions towards angels and majestic point system.

2. can't use free compilers, the sources contain microsoft-specific code, so you must use a visual studio. You can probably find a VS6 somewhere around the web to use for free.

Share this post


Link to post
Share on other sites

@HBPLD: nice what you got there, we already have this in nemesis for a couple months now, they're called "Limited Items" in nemesis ;)

Also a very nice attemp to make the "old" aresden/elv maps work, although i see the Icebound Bridges in the right-top corner of your screen. Nemesis has overcome this obstacle about a year ago.

Share this post


Link to post
Share on other sites

@HBPLD: nice what you got there, we already have this in nemesis for a couple months now, they're called "Limited Items" in nemesis ;)
Also a very nice attemp to make the "old" aresden/elv maps work, although i see the Icebound Bridges in the right-top corner of your screen. Nemesis has overcome this obstacle about a year ago. 

 

Old maps its easy to fix look:)

 

12438076614525998499.jpg

70665958318947017354.jpg

 

18320075004089772149.jpg

95525852567934193669.jpg

Share this post


Link to post
Share on other sites

@HBPLD: Yup, rooftops easy to make them not-drawn, in one SS you're ON TOP of the roof, so your rooftop doesn't draw OVER the character as it is suposed to be like that.

Adding limited, corrupted, fragile and bound items is fairly easy too if you know how to code.

Adding the non-duplicate items, cityhall menu's and item descriptions is also easy.

It's just a matter of what you want, which course you're going with your server, yet nemesis was first with these, therefore you're just making a copy of nemesis but will never get it fully completed or done because by the time you're half way your copy of nemesis, we'll have new stuff released. ;)

Share this post


Link to post
Share on other sites

men i do this for my self;p

i dont create any server ;P

i lazy, dont worry :D

 

yes i was copy, sorry for this but i very like nemesis server ;P

Share this post


Link to post
Share on other sites

men i do this for my self;p

i dont create any server ;P

i lazy, dont worry :D

 

yes i was copy, sorry for this but i very like nemesis server ;P

 

As long as you don't run a server with it, i don't really mind, as nemesis was first anyway and nemesis has it up-and-running already for a long time.

It's good to hear people like nemesis ;)

Share this post


Link to post
Share on other sites

i really envy all your skills. i really want to get good at programming, im a beginner java student, but hb code makes no sense to me! (i know hb isnt java but syntax seems almost same)..

Share this post


Link to post
Share on other sites

i really envy all your skills. i really want to get good at programming, im a beginner java student, but hb code makes no sense to me! (i know hb isnt java but syntax seems almost same)..

 

syntax is 99% equal if it comes to base types, in java you just have the java-base classes to use (java.*) which offers alot possibilities. In C++ this doesn't exist, you have to include Windows libraries or use the .NET framework if you want aprox equal or more abilities as in java.

 

And most important, C++ has pointers, java doesn't.

Share this post


Link to post
Share on other sites

Because everybody loves pointers.

 

Yup, cuz pointers create memory leaks... pointers create access violations... pointers create buffer overflow... pointers create memory override... pointers just cause massive headaches if you don't know how to use them.

Share this post


Link to post
Share on other sites

After reading the topic and the reading the first comment you posted White, I'm a bit confused to what you're trying to imply here. Are you guys trying to add a cool down to activation items drop rate? or are you trying to make items with activation cool downs like x weapons and medusa?

 

I think it would be great if we had more items with cool downs or just simply adding addition bonus to items. I have no idea how coding words, but I'm sure its insanely complicated trying to creating new things.

 

Although, Helbreath is so unique and fun because of the simplicity game mechanics, so I don't know if adding too much would be a great idea. Thats just what i'm wondering...: /

Share this post


Link to post
Share on other sites

After reading the topic and the reading the first comment you posted White, I'm a bit confused to what you're trying to imply here. Are you guys trying to add a cool down to activation items drop rate? or are you trying to make items with activation cool downs like x weapons and medusa?

 

I think it would be great if we had more items with cool downs or just simply adding addition bonus to items. I have no idea how coding words, but I'm sure its insanely complicated trying to creating new things.

 

Although, Helbreath is so unique and fun because of the simplicity game mechanics, so I don't know if adding too much would be a great idea. Thats just what i'm wondering...: /

 

The idea is to add a cooldown to the item, let's say you got a xelima rapier, you activate it, your char needs to 'cooldown' from activating such a powerfull weapon.

Right now it's plain simple to continue activating and killing your enemy, you pass it on to your friend and you activate again and kill your enemy.

What we want to do is add a 'cooldown' to the item itself too, so after activating, your character must cooldown to use any other activation item, but the item itself also needs to cooldown from its activation, meaning that passing on the weapon, your friend has to wait untill the weapon cooled down sufficiently to use it once again.

Likely the cooldown will be item dependant, meaning that an IE sword needs less cooldown then a xelima item for example.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this