Archived copy of war3source.com, the War3Source forum (2009–2020), rebuilt from the Internet Archive by wc3mods.net. This page was captured on 2012-10-25 (original capture). Forum · All archived topics · Wiki · Bug tracker · Blog
Chat

War3:Source
October 24, 2012, 08:44:08 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Download: http://war3source.com/index.php?board=9.0
What is War3Source?: http://war3source.com/index.php?topic=200.0
Sample Stats: http://war3source.com/war3stats
Steam Community Group: http://steamcommunity.com/groups/war3source
War3Source SVN Checkout: http://ownageclan.com/svn/war3source/
War3Source servers: http://www.game-monitor.com/search.php?vars=war3_version=
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: My thoughts about improving ShopItems  (Read 358 times)
Glider⠠⠵
Global Moderator
Sr. Member
*****
Posts: 413


⠠⠵


View Profile
« on: July 05, 2010, 02:53:24 PM »

Hello mates, I'm a long time TF2 player who has had his share of RPG mods on various source games. Recently I also got into hosting my own little War3Source matches locally with a friend against bots. At my workplace I'm a Python programmer so I know a thing or two about programming in general. A few days ago I tried to improve upon my game experience by toying around with the shop items. Now I don't have a single clue about how this SourcePawn stuff works, but I'm fit with Python, Basic and know a few basics of other languages (C, Java, Ruby). The gamecode for shopitems is a big cluttered mess right now, so I thought about a few ways to improve it. Now as I said, I don't know much SourcePawn, so I will be posting my examples and ideas in some basic "pseudo-code".

My main grief
- Adding new shopitems is too "static". You have to add your item to a list of shopitems, make a function that appends it to the shopmenu, tell the game to remove it when you die and when you've done all that - then you haven't even given it a effect yet! Not only is this overly complicated, but it's also very error-prone. I added some items for testing that did not work out so well and removing them afterwards was a real pain, as I had to look in the code for references to them.

How to improve the ShopItems
Make a basic "ShopItem" class. This class has the following parameters wich I will explain in detail afterwards:
- Name
- Description
- Cost
- Type
- Function
- Game

Name: Self explanatory. This is the unique identifier that is currently hardcoded into the plugin.
Description: The description of the item when viewed in detail
Cost: The cost to the players
Type: What kind of item it is. This basically tells the game, when the effect is invoked. This would refer to a state like "UponDeath", "DamageTaken", "DamageInflicted", "UponRespawn", "Constantly" and "Instant". Later you could improve this with states like "OnFire", "WhenUbered" or "AfterBombPlanted"
Function: The method to invoke when this item should be used
Game: The game this item is for. All, TF2, CSS etc.

Now to create a ShopItem, you would invoke a constructor. This constructor is currently extremly static, as you basically have to tell the game all the stuff manually. A simple constructor class would ease up the pain on the item developer very much and improve the way you could redistribute items. Right now if I wanted to post one of my current items, I'd have to tell you where to add what bit of code in all detail. With this, I could just post 2 snippets, the constructor and the function I will explain in greater detail and everyone could add it easily. Also maintaining custom items when there's a update will be much much easier. An example:

War3Source_CreateItem("claws", "Increase your damage", "3", "DamageInflicted", "ClawsDamage", "All")

Then there would be a function called "ClawsDamage", wich is basically part of the if statement in the DamageTaken now.

How to handle the items
Right now, everything is so hardcoded into the system. OnDamage the game checks "does the attacker have xy?", "does the attacker have yx?". This is something that's hard to maintain and update. I'll start from the beginning with my proposal:

1. A player buys a shopitem. The menu passes the shopitem to the plugin, the plugin checks if the player has enough crystals and if he does, the players ShopItem[PassedItem] attribute gets set to True.

2. Let's say the item was a damage modifier, increasing the damage he deals. When he deals damage, the event for this hooked. Now the event iterates over all possible shopitems, generated dynamically by the shopitems create function in the plugin.

3. The attacking player owns item xy -> Victim and Attacker are passed to Shopitem[xy]s "Function" that was set in the constructor. This function handles the extra damage and then returns to the OnDamage hook.

4. Next we iterate over all of the items of the victim wich have "DamageTaken" as Type...

Next would be the death event. Right now, all items are manually checked and then removed. This just baffled me when I saw it for the first time. Why not make a simple approach? Iterate over all possible items and set them all to false in the players "owns shopitem" property. The event would be built something like this:

if player has scroll of respawning:
  respawn
if player has ankh of reincarnation:
  player.ownsitem[Ankh] = false
  break
else:
  for items in shopitems:
    player.ownsitem[items] = false

This way we first check if the player has a scroll of respawning. If he does, we respawn him. Then we check if he has an Ankh. If he does, we remove it and break here and don't go any further. If he doesn't, we simply set the ownership for all items for that player false, since we should we check if he has each item individually? Nothing to lose here (unlike for the player)

Addendum

I will now explain the other types besides "DamageTaken" and "DamageInflicted" I mentioned earlier.
- UponDeath: Invoked when the player dies. An example would be a scroll of respawning.
- UponRespawn: Invoked when a player respawns. Mole would be an example for this.
- Constantly: A periodical event, could possibly also count as "Instant", since it instantly calls a timer with infinite repeats.
- Instant: Something that works right now. An example would be a item that heals you for a specific HP or something.

I hope you understood the basic gist of what I was trying to get across. I'm for a more object orianted approach that makes the coding easier on the developers and the people wanting to be developers. I don't know much about SourcePawn, so feel free to teach me why this isn't possible or wasn't done by now. Coming from Python I'm not used to such a static way of coding.
Logged

Ownz
Developer
Administrator
Hero Member
*****
Posts: 2046



View Profile WWW Email
« Reply #1 on: July 05, 2010, 03:29:11 PM »

let me do a short paraphrasing, correct me if im wrong

the war3source main should handle more of the shopmenu's functions
such as: when to trigger it, remove it on death,, etc so the item itself does not need to hook the events
and calls a function in the shopitem plugin to make the effect. calling a function by name is possible by GetFunctionByName

---------
my thoughts: this is a great idea, i didnt invent this style but the previous (currently mia) developer made this
i made the psudo-class "cooldown manager" to handle all the cooldowns

i want you to know: sourcepawn is not object oriented, to copy an object oriented style we use natives, forwards, and static arrays. a race is sort of an object, a shopitem is sort of an object, but the functions (methods) are currenly done within the races. You need to learn sourcepawn before considering which implementation is better. When you are dealing with sourcepawn, you need to think static and typeless, do not think in terms of ES or try to copy it's functionality

what we did was instead of registering every function call from each race, we made standard forwards and passed along parameters to identify which race/item is suppose to handle it , ie: OnSkillLevelChanged( client, race, skillnum)
we left the race responsible for hooking its own events

each race / item hooks its own events with some exception such as OnTakeDamage which is from sdkhooks, but i like the idea that the main function hooks it once and passes it to every race/item

« Last Edit: July 05, 2010, 03:31:30 PM by Ownz » Logged

DarkEnergy
Ownz
Developer
Administrator
Hero Member
*****
Posts: 2046



View Profile WWW Email
« Reply #2 on: July 05, 2010, 08:52:47 PM »

general events to be implemented

new Handle:g_War3GlobalEventFH;

new Handle:g_OnWar3EventSpawnFH;
new Handle:g_OnWar3EventDeathFH;
new Handle:g_OnWar3EventPostHurtFH;
Logged

DarkEnergy
Ownz
Developer
Administrator
Hero Member
*****
Posts: 2046



View Profile WWW Email
« Reply #3 on: July 05, 2010, 08:56:55 PM »

give me an item you wish to create, and we can see how easy or hard it is to pseudo code it
Logged

DarkEnergy
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!