|
Post by docclox on Feb 9, 2011 17:35:28 GMT -5
As suggested, this is a thread to discuss bits of code we don't understand, proposed changes, and generally discuss coding issues. It's as much about making sure we understand existing code as it is about finding better ways to do things And it's not just about daisy's code - it's about everyone's.
Let's start with something fairly simple:
//cacalate to 'd' decimal places and round to nearest function dpn(x:int, d:int) { x = x * Math.pow(10, d); var y = Math.round(x); y = y / Math.pow(10, d); return y; // Created by Mark Freeman // markfreemanwebdesigner@yahoo.com }
I don't think that works. It looks like the intention is that you can call it like this:
trace(dpn(123.456789, 3)) // prints 0.123?
So, 123.456789 * 10^3 = 123456.789 round that to 123457 divide back down 123457 / 1000 = 123.457
But it doesn't work like that. The x parameter is typed as int. So the parameter is going to be type coerced into an integer. That basically truncates the Number and the fractional part is lost by the time it gets into the function. So what really happens is:
123 * 1000 = 123000 round 123000 to 123000 123000/ 1000 = 123
and the bottom line is you might as well have written int(x)
This goes doubly for its use in totalPoint (which I'm busy moving to the new Girl class)
GameArray[whatGirl].girlSexTotal = dpn(GameArray[whatGirl].girlSexTotal, 0);
Now bearing in mind that 10^0 is 1, if we pass 123.456, internally we get
123 * 1 = 123 round(123) = 123 123 / 1 = 123
So, assuming I have that right, and didn't miss anything important, there are two fixes for this.
Firstly, make parameter x type Number. Then we at least pass a float and it should work as intended.
Secondly, if all we want is to round to the nearest int, use Math.round directly.
Thirdly, if all we want is to lose the fractional part. just cast it to an int
int(123.456) == 123 int(456.789) == 456
|
|
|
Post by daisy_strike on Feb 9, 2011 17:43:37 GMT -5
Ugh actually I stole that code. It rounds to the decimal put in. And my name is not mark freeman... But it looks like your right about them being converted to ints... they should have been number. Otherwise your right it probably only rounds to 0 decimals... which was the only thing I was using it for.
Daisy
|
|
|
Post by docclox on Feb 9, 2011 18:12:50 GMT -5
I'll make the dpn function go away in that case. And you didn't steal it, you credited the author. It's only stealing if you claim it as your own [edit] I think this may explain the "feast" problem: function healthRaise(raise:int, girl:int){ if (checkForEffect(3, whatGirl)) { if (raise == 0) { GameArray[girl].girlHealth = GameArray[whatGirl].girlHealth - playerCharacter.charHealthDrop - 5; } else { GameArray[girl].girlHealth = GameArray[whatGirl].girlHealth + raise - 5; } } else { if (raise == 0) { GameArray[girl].girlHealth = GameArray[whatGirl].girlHealth - playerCharacter.charHealthDrop; } else { GameArray[girl].girlHealth = GameArray[whatGirl].girlHealth + raise; } } maxStatCheck(); }
Now if the parameter "girl", and the global "whatGirl" are the same (as they usually are) then this works as expected. But if they're different... GameArray[girl].girlHealth = GameArray[whatGirl].girlHealth + raise; Then the change in health uses someone else's stats as the base. Which sounds like what's been reported for some cases where a girl cooks a feast. I'm busy moving most of these funcs to the new Girl class, so unless there's a good reason to do this, I'll fix it there.
|
|
|
Post by zenzou on Feb 10, 2011 0:20:16 GMT -5
What do you get when you have a bunch of nerds and geeks hanging out? Work. --- Anyways, since so much relies on the girl classes and functions, it seems like we really kind of do need to wait till you're finished with that. Of course that doesn't mean we can't still do reviews.
|
|
|
Post by docclox on Feb 10, 2011 7:02:02 GMT -5
I'm trying to understand Effects.
It started out because I needed to know what the effect numbers were for bit of the girl code. So I wound up doing this:
package { class Effect { public static const Virgin = 0; public static const In_Love = 1; public static const Insane = 2; public static const Tetanus = 3; public static const Lactating = 4; public static const Perfect_Pitch = 5; public static const Charismatic = 6; public static const Creative = 7; public static const Alcoholic = 8; public static const Exhibitionist = 9; public static const Lycanthrope = 10; public static const Natural_Fighter = 11; public static const Mean = 12; public static const Smart = 13; public static const Stupid = 14; public static const Submissive = 15; public static const Trusted = 16; public static const Teacher = 17; public static const Undead = 18; public static const Unhappy = 19; public static const Vampire = 20; public static const Wounded = 21; public static const Sick = 22; public static const Nature_Lover = 23; public static const Inspired = 24; public static const Artificial = 25; public static const Comatose = 26; public static const Badly_Wounded = 27; public static const Drunk_1 = 28; public static const Drunk_2 = 29; public static const Drunk_3 = 30; public static const Chef = 31; public static const Master_Chef = 32; public static const Demotivated = 33; public static const Nocturnal = 34; public static const Not_Milked_1 = 35; public static const Not_Milked_2 = 36; public static const Not_Milked_2 = 37; public static const Max_Effect = 37; public static const Number_of_Effects = 38; } }
The idea being that we can replace
checkForEffect(3, whatGirl)
with
girl.has_effect(Effect.Tetanus)
Which is hopefully clearer.
Anyway, this lead me into the depths of funcStatCompareArray in gametext.as where the effectCompareArray gets initialised a bit like this:
var CompareEffectVirgin:Array = new Array( new EffectVirgin(), // picture 0, // effect_id "Virgin", // name "This girl has never had straight sex and still has her hymen. Happiness raised, unless lust becomes too high.", -1, // item number (none in this case) 2, // stat affected (counting from obedience, happiness == 2) 0, // unknown 0, // ditto null, // marker to find the next field 0 // also the effect id? ); effectCompareArray.push(CompareEffectVirgin);
I worked out this much from the comment at the top of effects.as, plus a bit of detective work, but there are a couple of fields I can't figure out at all, and I'm not sure about the rest if truth be told. The two effect IDs see, to always be the index of the entry. The second one is used to determine what changes are made to girl's (or player's, or assistant's) stats as a result of the effect, so it could be different, although I'm not sure why we'd want that. The null marker is searched for before applying the last effect id, suggesting that there could be a variable number of values prior to that. Stat/quantity pairs? I'm at a loss.
Anyway, back to the coalface...
|
|
|
Post by daisy_strike on Feb 10, 2011 20:40:59 GMT -5
//Picture, item number, Name, Text, stat it affects, how much each day
theoretically the effects can modify 20 different stats that is why there is null... what happens is the game goes through chunks of 4 modifying stats. Example would be good.
result, 0, "Virgin", "This girl has never had straight sex and still has her hymen. Happiness raised, unless lust becomes too high.", -1, 2, 0, 0, null, 0);
So this increases happiness... the 0 for once in a day.
result, 0, "Virgin", "This girl has never had straight sex and still has her hymen. Happiness raised, unless lust becomes too high.", -1, 2, 0, 0, -2, 1, 1,1, null, 0);
Would increase her happiness and her slave skills once a day.
This was how it was supposed to work but the system sort of fell apart do to me just manually putting all the stuff in. I used the null as a divider... probably not the best way to do it but the items are the same way.
Daisy
|
|
|
Post by docclox on Feb 11, 2011 3:13:02 GMT -5
result, 0, "Virgin", "This girl has never had straight sex and still has her hymen. Happiness raised, unless lust becomes too high.", -1, 2, 0, 0, -2, 1, 1,1, null, 0); Would increase her happiness and her slave skills once a day. OK, so I'm not sure what the negative number is for. Is it just a marker like the null? So the sequence would be negative-marker, stat-number, stat-increase, times-per-day with an increase of zero meaning "add one" and times per day of zero likewise meaning "once". Is that about right? Or did you mean that the second quartet raises all her slave skills - in which case I still don't quite understand. Also, is the effect number after the null ever different from the one following the result? This was how it was supposed to work but the system sort of fell apart do to me just manually putting all the stuff in. I used the null as a divider... probably not the best way to do it but the items are the same way. What I'd quite like to do, at some stage anyway, is to do the same thing as for the events and have something like this: var ef = new Effector({ movieclip : result, effect_number : Effects.Vigin, effect_name : "Virgin", effect_text : "This girl has never had sex .. etc etc", effects_stats : [ new StatEffect({ stat_name : Stat.Happiness, stat_change : 1, // add once times_per_day : 1 // one time a day }), new StatEffect({ stat_name : Stat.Happiness, stat_change : 1, // add once times_per_day : 1 // one time a day }), ] }); Which takes up a few more lines, but it's much easier to tell at a glance what's going on. [edit] Or it would be if this dratted forum would indent code tags properly. Let's try it in Pastebin:
|
|
|
Post by daisy_strike on Feb 11, 2011 3:41:42 GMT -5
The basic classes are negative
-1 for welfair -2 for slave -3 for straight -4 for lesbian -5 for futa -6 all sex (i think this is right futa and lesbian could be backwards)
by adding the null i could make it have large class and skill changes on one line and went it hit the null it would know that were done with class changes.
//raise welfair by 1 all, raise slave by 2 to all, raise maid cleaning ( i think), raise combat defense by 2 end effect changes -1, 1,1,1, -2, 2, 2,2,6, 1,0,0, 5, 0,2,0, null
and so on that way I can build a huge lists effecting all classes if i wanted to and the array would just keep looking in groups of 4 until it hit a null.
Your way looks easier to understand, though. Items are set up exactly the same way so that item can theoretically effect all classes and skills. But this was some of my original coding so I'm open to better ideas.
daisy
|
|
|
Post by docclox on Feb 11, 2011 5:03:23 GMT -5
The basic classes are negative -1 for welfair -2 for slave -3 for straight -4 for lesbian -5 for futa -6 all sex (i think this is right futa and lesbian could be backwards) by adding the null i could make it have large class and skill changes on one line and went it hit the null it would know that were done with class changes. //raise welfair by 1 all, raise slave by 2 to all, raise maid cleaning ( i think), raise combat defense by 2 end effect changes -1, 1,1,1, -2, 2, 2,2,6, 1,0,0, 5, 0,2,0, null and so on that way I can build a huge lists effecting all classes if i wanted to and the array would just keep looking in groups of 4 until it hit a null. Ah, I see. So that's why the four numbers there - one for the class and then three for the three skills. Gotcha. Your way looks easier to understand, though. Items are set up exactly the same way so that item can theoretically effect all classes and skills. But this was some of my original coding so I'm open to better ideas. Hey, it works. There's a lot to be said for that A more structured format would be easier to expand, though. Any event, I'm not going to do that until I get the Girl classes working - I want to keep it to just hte changes I need to implement that. One thing I would like to do for the girlEffectArray though: I'd like to make it an array of objects. To pick an example I've been working with just now: girlEffectArray = [ { effect_id: Effects.Tetanus, effect_mc: new EffectTetanus() }, { effect_id: Effects.In_Love, effect_mc: new StatLove() } ]
I wouldn't populate it like that in practice - that'd be down to addEffect, still. But it would mean that we could drastically simplify searches to see if a girl had an effect. Instead of looking up the clip from the global effect array, looping over the girl's array and comparing the stringified versions of both clips, we just loop looking for the effect_id passed as an argument. With a bit of luck I can even hide it all behind the Girl class interface. [edit] What the difference between picture id 2371 "Sex Masturbate Futa" and 2372 "Sex Masturbate Futa Self"? It sounds like the player is going to have the option to give himself a quick hand shandy I depart now in search of Brain Bleach...
|
|
|
Post by daisy_strike on Feb 11, 2011 20:09:56 GMT -5
self should be masturbating bj. Do I need to go into details...
Daisy
|
|
|
Post by docclox on Feb 12, 2011 4:31:11 GMT -5
self should be masturbating bj. Do I need to go into details... I think that's sufficient information for my current purposes
|
|
|
Post by compuscribe on Feb 12, 2011 13:37:57 GMT -5
Knowing how much Daisy hates working on the save functions (and since I don't think anyone else is working on it, right now), I thought I'd take a crack at trying to pin down the lingering problems that I and others have been running into. (Without a working save, this game is patently unplayable, for me, so it's kind of a selfish thing.) I also figured I'd add the ability to save in multiple slots, while I'm at it. Even if you don't use it right away (I default to just using slot 1, automatically), at least it gives you room to expand once we get all of the kinks worked out.
I've only just started looking at it, so I haven't gotten very far, but here's what I've got so far.
function saveButtonClick(e:MouseEvent) { saveGame(1); //Save in slot 1, by default }
function saveGame(slot:int) { var myLocalData:SharedObject = SharedObject.getLocal("otherworld"+String(slot)); //Use slot # to build a distinct name for this file myLocalData.data.doesFileExist = new Boolean(true); var stringy:String = new String();
. . .
if(myLocalData.flush()) { storyHopper.push("Game Saved"); } else { storyHopper.push("***SAVE FAILED***"); } myLocalData.close(); //We have our save, so close the sharedObject to ensure it doesn't continue to gather data mainTextStart(0, 0, 0); }
That's only the save functionality, so it will not work, as is (and they're, by no means, guaranteed to be the only changes), but I'm throwing what I have out there to get some feedback on the general approach.
For the most part, the key areas should be fairly self-explanatory, I think, with the possible exception of the myLocalData.close(). In AS1, I used to delete the sharedObject after flushing it, but that seems to generate errors in AS3, so I'm closing it, instead. Since we still seem to be having problems with the game occasionally saving when it shouldn't, I'm going to go through and systematically close all of the sharedObjects when we're done with them. It may not solve our problems, but it certainly couldn't hurt. (I'm closing it, not clearing it, so the data in the file should be fine. I'm just severing the connection between the program and the file. At least, that's my understanding of it.)
I do have one question, though. What's this:
var stringy:String = new String()
Near as I can tell, it isn't used anywhere else in the saveGame() function, so it's probably safe to get rid of it, but I thought I'd get confirmation before I tried. I don't want to break something else.
Lastly, when I finish, someone else may have to check it out for me, because I can't seem to build a working version of the game. I checked out the code in the trunk, so I'm assuming it's at least relatively up to date, but when I try to test it, it seems to build fine (no errors) but I only get the title screen with no buttons, so I can't do anything to test my changes. I'll admit that I never tried building a Flash program this elaborate before, so it's entirely possible (or even likely) I'm doing something wrong, but I have no idea what that would be. (I'm using CS4, if that matters. I'd rather not have to go through the hassle of upgrading if I don't have to, though.)
On a side note, before anyone asks, no, I don't wish to be added to the SVN. I've got too many other projects. I wouldn't be able to do much, anyway, so I'd just cluttering things up. In fact, I'm pretty sure this would be my sole contribution, but at least I might actually do something to earn that recognition in the credits. (Docclox did all of the heavy lifting, last time. I merely explained why it was a good idea.)
[Edit] The reason it isn't building properly is because it isn't acknowledging the presence of any actionscript (That also explains the lack of errors.) I'm not entirely sure why that is, but I'll look into that after lunch.
|
|
|
Post by daisy_strike on Feb 12, 2011 15:10:13 GMT -5
I actually updated the load function in the last few days. So might want to use my version and not the trunk.
And it looks like that might just be a variable that has lost its reason for existing.
Daisy
|
|
|
Post by zenzou on Feb 12, 2011 23:30:06 GMT -5
Hmm, I've having random load errors using your current branch.
|
|
|
Post by compuscribe on Feb 13, 2011 3:21:51 GMT -5
A quick update: after spending half a day trying alternately to pin down exactly which parts are screwing up my attempts to get a successful build and scouring Google for leads based on the handful of error messages I was able to hunt up, I've gotten precisely nowhere. (Well, that's not entirely true. I think I've got a better idea what's going on, but none of the suggestions I've found have helped in the slightest.) It's definitely looking like I'm going to have to do this the hard way: write my own file to test my ideas for the saves, then port them over and hope for the best.
Anyway, it's too late for me to try anything more, tonight, but I've gotten sidetracked enough. I'll get back to the saving/loading functions tomorrow, to see what I can do.
[update - part 2] It seems close() wasn't doing what I thought it did, so, I've started assigning the SharedObjects to null, to get rid of them, once we're done with them (as suggested by the compiler errors I was getting when trying to delete them). As far as preventing anything from accidentally writing to the save file, it seems to be doing its job.
I've also found at least part of the problem, and it's the reverse of what we had before. Earlier, the saves weren't taking, because we weren't flushing the saves. Now, they're being altered, after the fact, because we are flushing the loads. Loading should be a read-only operation, so we don't want to be writing to the hard disk, which is essentially what flush() does. Combine that with Flash's tendency to pass objects by reference, rather than value (a problem we've encountered elsewhere while trying to copy objects), and you're heading for trouble, as the game tweaks the values of those objects over the course of events. This is further compounded by Flash's tendency to write any currently open SharedObjects to the hard disk when the program closes, making it all the more critical that we shut down the SharedObjects, once we're done writing to them.
I'll keep looking, to see if I can find anything else, but it's already looking better, at least in my small-scale, proof-of-concept tests.
[Edit 2] Unless anyone can think of a reason why we need decimal numbers for any of the index values for the loops, I'm also changing them from Numbers to ints, while I'm at it. Since integer arithmetic tends to be a bit faster than decimal arithmetic, if you only need an integer, it makes more sense to use an integer.
Also, since this is, now, a community project, I thought I'd throw this out to the community (at least the ones it's most likely to impact). I tend to name the index variables for my loops i, j, k, and so on, but I noticed the savingloading.as file tends to use i, i2, i3, etc. On the one hand, they're equally arbitrary, but it seems like it might be easier to confuse which i is which (not to mention the risk of confusing the number as part of an arithmetic computation). It could just be me, though, and since I'm likely to not be the one responsible for maintaining the file, I thought I'd get other people's opinions before I went through and changed them. After all, the point is to help everyone else, not to make it easier for me.
|
|