Jump to content

Recommended Posts

Posted (edited)

Hello members,

 

Since my mobile service provider has an app and allows me play a game in order to win certain prizes like (extra mbs, msgs, talk time ) when i put a code 

i decided to create something similar to l2.

 

Explaination:

  1. Every player can get a coupon.
  2. Coupons have categories : Silver,Gold,Platinum
  3. Each category has its own reward list (configurable)
  4. Coupons can be deleted , redeemed  and show their rewards by writting /coupons
  5. You will win a random reward based on coupon's category and grade type
  6. Create your own condition and add a new coupon to this player.
  7. Grade Type added (No grade,D,C,B,A,S) based on the current level of the player, the grade will not change once the coupon activated
  8. Players have daily limit.
  9. Coupons Task Manager running and every day the time you will set all limits will be lifted.

If you guys find any mistakes please let me know i would really appreciate it, cause i want to learn alternative and easier ways  ;)

The code is working properly.

 

Coded on aCis 370 rev.

 

Video

 

Code

 

Htmls

 

Database

 

 

DROP TABLE IF EXISTS `coupons`;
CREATE TABLE `coupons` (
  `owner_objid` int(10) DEFAULT NULL,
  `coupon_id` int(11) NOT NULL DEFAULT '0',
  `coupon_category` varchar(45) DEFAULT NULL,
  `grade` tinyint(3) NOT NULL DEFAULT '0',
  PRIMARY KEY (`coupon_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
 
ALTER TABLE `characters` ADD COLUMN `couponsused` tinyint(3) NOT NULL DEFAULT 0 AFTER `death_penalty_level`;
 

 

 

 

Player configs:

 

 

# Maximum coupons per day (0 = disalbe)
# This limit will be lifted at the time you will set in ResetCouponsLimitAt config
CouponsLimit = 5
 
# Time for the daily lift (default 00:00)
ResetCouponsLimitAt = 00:00

 

 

 

Special thanks to Tryskell.

 

P.s I do not have voiced command handlers so i used usercommandhandelrs.

if you want too, you have to add 1 line in commandname-e.dat

115	114	a,coupons\0
Edited by melron
  • Upvote 5
Posted (edited)

Not bad idea, sort of lucky wheel :P

 

To make it more complete create an item which could be droppable from a Rb, let's say, and this item will generate the coupon code, else some exchange option, x item for the coupon code. :)

Edited by SweeTs
Posted (edited)

- Rewards should be handled by a static map <String, List<CouponReward>> (basically a map with 3 entries), where string is the type of coupon. Your coupon will only stores coupon type (gold, silver,...) and not rewards.

- CouponManager coupons List can't be an ArrayList, you will get ConcurrentException. Either use ConcurrentHashMap, or CopyOnWriteArrayList (which is really horrible on .set()).

- final String DELETE_COUPON = "DELETE FROM coupons where coupon_id = ?"; and all other queries must be private static final and set out of the method (or at least passed directly the parameter in prepareStatement).

- getCouponId : use Rnd from commons package, and not Random. The method probably can be cleanup by a lot (using StringUtil.LETTERS_AND_DIGITS) and a scramble method.

 

The whole reward acquisition should be reworked. The basic concept is, your coupon is linked to a RewardType (SILVER, etc), your reward map .get( retrieve all possible rewards. Then you only need to Rnd.get(rewards) to retrieve the associated reward.

 

Atm you pass all possible rewards on each coupon, which is totally uneeded and generate a lot of pointless data. The whole bypass "redeem" needs to be reviewed too.

 

PS : if you want to enforce the coupon type, you can create RewardType enum, and store rewards under an EnumMap rather than a HashMap <String, List<CouponReward>>.

PS2 : at least you thought about coupon id already existing, good job :).

Edited by Tryskell
Posted

Well as i can see there are serious problems , should a mod move it to the proper section until it get fixed? It is not worth for someone to get it if its not completed.

 

 

Nick,Tryskell i love you guys. I will try to fix it as soon as possible :)

 

Thank you pirama,Sweets!

Posted (edited)

Well as i can see there are serious problems , should a mod move it to the proper section until it get fixed? It is not worth for someone to get it if its not completed.

 

 

Nick,Tryskell i love you guys. I will try to fix it as soon as possible :)

 

Thank you pirama,Sweets!

 

Simply share it under a v1, v2 model with a little changeset for each version.

 

The only real serious problem impacting the stability of your custom is the ConcurrentException if numerous players got/remove coupons in same time. Use ConcurrentHashMap.newKeySet() to handle it properly. Other changes are readability, performance and optimization.

Edited by Tryskell
Posted

Some comments.

  • Why are you returning null instead of empty list when a list is empty? It is easier and safer to handle empty lists than null statements that throw NPEs

 

Nice try overall. Thanks for the share.

 

I don't agree with this, empty lists, empty string etc have terrible performance, I always go with null checks, NPE means bad code that should be fixed not handled, imho NPE should be an Error and not an exception

Posted (edited)

Your opinion versus the whole internet.

 

Can't get it, so you're saying that few unnecessary calls that give you a dummy empty list are cleaner than nullptr ? Its obvious that this emptylist should be used on other cases but here? Explain me why this is worst and I will go to fck off right away

 

final ArrayList<Coupon> coupons = getCoupons(player);

if (coupons == null)

{

     //msg and exit

}

{

else

{

   for (Coupon c : coupons)

        c.something();

}

 

if getCoupons returns empty list instead of null, the flow of the rest code is dumb and nonsense. null checks are as fast as 1 == 1

Edited by xxdem
Posted

Why you even share it for free? I mean, you probably spent time on this, maybe even much time.

By the video i see its a unique idea, never seen something on other servers.

 

You probably should fix all the code the guys mentioned above and try to sell it.

because community is in need of new things i guess. It's a good idea to make new shares like old times.

Posted (edited)

Why you even share it for free? I mean, you probably spent time on this, maybe even much time.

By the video i see its a unique idea, never seen something on other servers.

 

You probably should fix all the code the guys mentioned above and try to sell it.

Designatix answered you but it's not only this thing.

Imagine this topic in marketplace section with these bugs inside ;)

Also there are many shares that deserves your question and not mine for sure :P.

I'm gonna update it to be completed and reshare it

Thank you for your good words my friend!

Edited by melron

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.




  • Posts

    • Since I write everything in the guide file. Windows: Download Python from the official website: Download Python. During installation, make sure to check the option "Add Python to PATH". >>>How? just check it in google.com Complete the installation.     There is a file called guide there I have all the details... [DropSettings] RateDropItems = 1879, 1875 RateDrop = 4 InputFolder = npc OutputFolder = npc_new Download
    • 1. gameserver\data\string\strings_en.properties   drop.group.html=<br1> drop.rewardData.html=<table width=500 height="42" border="0" background="L2UI_CT1.Windows_DF_TooltipBG"><tr><td width=32 height=32><img src=%icon% width=32 height=32></td><td width=310>%item%<font color="LEVEL"> %drop_min% - %drop_max% </font><br1> Drop Chance : <font color="LEVEL">&nbsp;%chance%&nbsp;</font><br1></td></tr></table><br1> drop.rated_grouped=<br1> drop.not_rated_grouped=<br1> drop.not_rated_not_grouped=<br1> drop.sweep=<font color="E7C94E"> Spoil: </font><br1> The following HTML code will work if you have the capability to adjust the window to any dimensions you want. 2. gameserver\data\html-en\actions\rewardlist_info.htm <html noscrollbar> <title>Drop List</title> <body> <center>     <font color="LEVEL">%npc_name%<font><br1>     <table>     <tr>         <td><button value="Normal" action="bypass scripts_actions.RewardListInfo:showReward 0 RATED_GROUPED" width=150 height=20 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>         <td><button value="Spoil" action="bypass scripts_actions.RewardListInfo:showReward 0 SWEEP" width=150 height=20 back="L2UI_CT1.Button_DF_Down" fore="L2UI_CT1.Button_DF"></td>     </tr>     </table>     <img src="l2ui.SquareGray" width=490 height=1><br1><br1>     <font color=995312>%info%</font>     %paging% </center> </body> </html> resize_x=550 resize_y=360 The .htm files are adapted for custom dimensions. You must have support in your client for handling custom HTML window sizes. and it looks like this:  
    • MaxCheaters used to be a glorious pit of barely functioning dreams. I logged in DAILY to witness war crimes in Java. Now it’s just 14 dudes reposting the same extender like it's a sacred text AND HALF OF YOU CAN’T EVEN UPLOAD FILES WITHOUT A .RAR INSIDE A .RAR INSIDE A .RAR WITH A .TXT THAT SAYS “NO VIRUS.”   You used to steal from Russians with pride. Now you steal from each other with broken links. What happened? Where are the insane flame threads? Where’s that one guy who kept threatening lawsuits in 2015? AND TO THE MODS — what are you even moderating now? Someone just posted a thread titled “HELP ME CLIENT CRASH WHEN WALK,” and the only reply was "UP."   WAKE UP MAXCHEATERS OR I SWEAR TO GOD I’LL START POSTING TUTORIALS IN WINGDINGS.
    • I’m not personally involved, but after observing recent activity on the forum, it's clear that things have become highly polarized, not because of technical issues, but due to personal disputes, insults, and public drama. It's unfortunate to see that instead of healthy knowledge sharing, discussions are turning into accusations, mockery, and downvote abuse. Everyone is free to contribute, disagree, or critique, but when respect is lost, the community itself loses its purpose. Whether someone shares files for free, sells services, or just helps others, their contribution should be judged based on quality, not personal grudges or "factions." It would be great to see the forum return to its original purpose: development, collaboration, and mutual respect. Those who truly care about the community should put personal conflicts aside and focus on the actual content, that’s where the real value is.
  • Topics

×
×
  • Create New...

AdBlock Extension Detected!

Our website is made possible by displaying online advertisements to our members.

Please disable AdBlock browser extension first, to be able to use our community.

I've Disabled AdBlock