Sunday, September 29, 2013

My Good Friends, Sort() and e.target.parent! - PrepHelp

Hello everyone!

Just a quick little update on PrepHelp. Since my last post I've worked out quite a few bugs. Here's a few things I got working:

  • Expiration date checking
  • Edit an existing item
  • Sort items by name, type, quantity, or expiration date
To check to see if the item is close to expiring gave me quite a bit of trouble. My initial thought process was to convert the dates into a separate number. For instance let's use 12/24/14 as our example date. The day would be the base number, so 24. Then you would add 100 for every month, which would bring us to 1,224. Then you could add 10,000 for every year, then compare the two numbers to see if the current day is still before the expiration date. As I'm sitting there I'm thinking to myself that this is not the way to try and check something like this. It's just nuts to complicate it like that. What I ended up doing was something more logical, and I hope a good way to do it. Basically, when I check the date I work backwards, starting with checking if the current year is the same, before, or after the expiration year. If it is the same year I then do the same check for the month, then the day. If it is within one month of expiring it will change a movie clip as a warning, then if the expiration date has passed it changes that movie clip again stating it is expired.

Here's the code that I came up with:
/* Since the add item date only has the last two numbers of the year we have to add 2000 since the date chek in unrealscript has a 4 digit year */ //If it is the same year, check if it is the same month if(foodInvo[i].ExpY + 2000 == currentYear) { //If so, check if it is the same day if(foodInvo[i].ExpM == currentMonth) { //If so, say it is expired if(foodInvo[i].ExpD <= currentDay) { item.expMarker_mc.gotoAndStop(3); } //If not, flag it as about to expired else if(foodInvo[i].ExpD >= currentDay) { item.expMarker_mc.gotoAndStop(2); } } //If the expiration date is a month away, flag it as about to expired else if(foodInvo[i].ExpM == currentMonth + 1) { item.expMarker_mc.gotoAndStop(2); } //If it is past the expiration year, flag as expired else if(foodInvo[i].ExpM < currentMonth) { item.expMarker_mc.gotoAndStop(3); } } else if(foodInvo[i].ExpY + 2000 < currentYear) { item.expMarker_mc.gotoAndStop(3); }

This helped me get the sort by date feature figured out as well, since it is basically doing the same thing. With the sort feature I used a delegate for the first time. Very interesting stuff, though kind of confusing. Basically a delegate allows you to use a function as a variable, sort of. In the case of the Array.Sort(delegate) function the sort function calls the delegate and the delegate takes parameter A and parameter B, compares them, and returns either -1(If your statement is true) or 0(If your statement is false). If -1(If I read the inline if statement correctly) is returned then the two elements in the array that are being compared will be switched. 

For sorting by date I ended up doing a little bit of my crazy number adding, though just by 1 or 2 instead of thousands. Since it is comparing two values and returning the larger I ended up adding or subtracting from one or the other depending on if the year/month/day were before or after the other.

Here is what the final code looked like:
//Calling the correct delegate switch(SortType) { case "Qty": //If SortType is quantity //use the SFBQ delegate FInv.Sort(SFBQ); break; case "Date": //If it is date, //use SFDB instead FInv.Sort(SFBD); break; default: FInv.Sort(SFBQ); break; } //The delegates //Sort Food By Quantity delegate int SFBQ(Food A, Food B) { //If sort quantity ascending is true if(bQUp) { //If FoodA.Quantity is greater //than FoodB.Quantity return A.Q > B.Q ? -1 : 0; } else { return A.Q < B.Q ? -1 : 0; } } //Sort Food By Date delegate int SFBD(Food A, Food B) { local int TempA, TempB; //If Year A is greater than B add 1 to A; if(A.D.Y > B.D.Y) { TempA += 1; } //Else, add 1 to B else if(A.D.Y < B.D.Y) { TempB += 1; } //If both have the same year, repeat down //through month and day. else if(A.D.Y == B.D.Y) { if(A.D.M > B.D.M) { TempA += 1; } else if(A.D.M < B.D.M) { TempB += 1; } else if(A.D.M == B.D.M) { if(A.D.D > B.D.D) { TempA += 1; } else if(A.D.D < B.D.D) { TempB += 1; } } } //If sorting Date ascending is true if(bDUp) { return TempA > TempB ? -1 : 0; } else { return TempA < TempB ? -1 : 0; } }

The other sorts were pretty straight forward since it would automatically check if the strings/ints were equal or not.

When I got around to adding the edit item I took almost all of the code for it from my add item popup. One thing I did change, though, was when the edit item popup comes up it will already have the information of the item being edited in the textfields. This would allow the user to change only what was necessary instead of having to re-input all of the information again. To do this I made use of the e.target.parent variable in Flash. Since the items are being added dynamically through code I found using the e.target or e.currentTarget keywords to be really helpful since it stores what movieclip/button that was the target of the event(Like the editItem_btn on a MouseEvent.CLICK event). One thing I had an issue with was that my target was my editItem_btn and all the information I wanted to access, so I could fill the edit item textfields, was in the parent movieclip item_mc. I tried several variations of parent.e.target and MovieClip(parent).e.target until I got e.target.parent. Then I could access my other textfields and all was well.

Anyway, hope that helps someone. Back to working on the search functionality!

Monday, September 16, 2013

Another Roadblock Avoided - PrepHelp

Hey guys!

In my last post I talked about the code project I was working on called PrepHelp. Over the past week and a half I have figured out most of the functionality for it. I have adding items, removing items, and am working on saving/loading inventory items to/from a config file.

To add an item I created a popup where you can enter any name, quantity, and expiration date. I also had to create a custom dropdown menu since I ran into issues when I tried the default component menu, as well as the Scaleform CLIK menu. With the default menu that comes with Flash it turns out it is not compatible, so while it works great in a strictly Flash project it throws errors when used with Scaleform. The CLIK one on the other hand has some issues where the dropdown part of the menu gets drawn over all other things in the swf, including the cursor(If you have the cursor in the same file). There are several workarounds, but I wanted the challenge plus this allows me to have more control over the graphics when I get to that part.

Also, if you forget to fill in all of the textfields on the Add Item popup then it will display an error and won't let you add the item till you fill the empty field.

When it came time to work on getting the saving and loading I ran into a pretty big problem...You can't save arrays to a config file. This should have been the first thing I checked before I started on this project, not after I have almost all of the framework done. Since the main reason I chose UDK over a strictly Flash based project was to utilize the config files.

Luckily, I found a post on the forums alluding to using a function to append/split a string and use that variable since you can save a string to a config file. Intrigued, I scoured the internet to find this magic function. After trying the wrong function I found the correct one. It is called SplitString. It is pretty handy. The first parameter is the string you wish to split. The second parameter is the delimiter, or what it looks for to know where to split it. The third is optional and it just asks if you want to cull empty elements. All of these broken up chunks are then stored in an array that is returned by the SplitString function. Here is an example of how I am using it to load my test inventory:

var config string FoodName; function LoadFoodInventory() { local array<string> FoodNameArray; FoodName = "How,now,brown,cow,this,goes,around,the,world"; FoodNameArray = SplitString(FoodName, ",", false); for(i = 0; i < FoodNameArray.length; i++) { FInv.Length = FInv.Length + 1; FInv[i].N = FoodNameArray[i]; } }

And as promised here are some screen shots of PrepHelp:

The test inventory using the SplitString function,
loaded from a config file.

The Add Item popup with custom dropdown menu.

Inventory after new item has been added.
From here I think it will mostly be copying existing code and fitting it for the medical inventory. and getting the search function all set up. I also have to get the expiration date thing implemented as well. I have a plan to tackle that, but it will just be a matter of plugging it in and seeing how it goes.

Well, that is all I have for now. Hopefully by next week I'll have the code wrapped up and started working on the visuals for it.

Wednesday, September 4, 2013

A Small Side Project - PrepHelp

Hey there!

Since we are waiting on models for N'Ferno, the firefighting game, and some more of the code base I decided to do a couple personal projects. I decided to start a small modeling project, and a larger code/design project. For the modeling I started modeling components of a camper van I own. I figured it was something I have ready access to and should be a nice little project. I wanted to do somewhat low poly, though have enough to make the objects look nice without going into a lot of detail. I finished up the dinette(the table and seats) and am working on the cabinet where the stove, fridge, sink, and electrical stuff is.

Here is the dinette:


When I get done with all of the models I want to go through and texture everything. Since I think texturing is my weakest point, this should be a good little exercise.

For my other project I had an idea to make a program to help people keep track of their long term food stores and medical supplies. This could be useful if you are prepping for the apocalypse or if you have food stored away in case of flood/hurricane/tornado or other natural disaster. The program would offer basic functionality. You would have the ability to add items into either medical or food items. Each item will have an expiration date, quantity, subcategory, and name. When viewing the list it will let you know if a particular item is getting close to its expiration date. There will also be a search function where you can search by subcategory(i.e. under food would be: grains, beans, meat, etc...) to help keep track of what items you have.

Due to the fact I haven't learned any other language besides UnrealScript and AS3 I decided to make it using UDK. I realize it isn't the best platform to make something like that in, but it is what I know. Eventually I will sit down and learn C++ or another language, but for now I'm working on expanding my knowledge of how to do things using UDK.

When I have the main body built I will post some pictures and possibly some code that I used to achieve it.