From 03cf7f457522966ea7d9d15783a5076a334e5afe Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Fri, 30 Dec 2011 19:57:19 -0800 Subject: [PATCH 01/13] Created a generic sqlite install in settings.py. Added model pulls to /rpf/admin.py --- jar.sql | Bin 0 -> 69632 bytes rpf/admin.py | 8 ++- settings.py | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 jar.sql create mode 100644 settings.py diff --git a/jar.sql b/jar.sql new file mode 100644 index 0000000000000000000000000000000000000000..902fa9299d35c458eef90e6a958fe003f0eeda2f GIT binary patch literal 69632 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 Date: Sat, 31 Dec 2011 15:27:27 -0800 Subject: [PATCH 02/13] Added a couple of user stories --- requirements/user_stories.txt | 16 ++++++++++++++++ rpf/admin.py | 6 +----- rpf/models.py | 5 +++++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 requirements/user_stories.txt create mode 100644 rpf/models.py diff --git a/requirements/user_stories.txt b/requirements/user_stories.txt new file mode 100644 index 0000000..176b975 --- /dev/null +++ b/requirements/user_stories.txt @@ -0,0 +1,16 @@ +**Alpha Create a user** +New user receives an email/msg invite from us. +User clicks the link and is presented with new user page. +User chooses a character name and clicks a button to make sure it doesn't already exist. +User chooses metric/imperial default option. +User selects a gender. +User enters their email address. +User clicks save/submit button to create their account. + +**User chooses a guild** +User receives an invitation from a guild to join. +User visits guild page to see what the guild is about. +User clicks "Join Guild" button. +User is directed back to the guild page with a welcome message and member only view. + +**User enters a workout** \ No newline at end of file diff --git a/rpf/admin.py b/rpf/admin.py index 98ad89d..d72ce04 100644 --- a/rpf/admin.py +++ b/rpf/admin.py @@ -1,11 +1,7 @@ from django.contrib import admin # import all the models from the RPF -#from jarnheim.rpf.models import * -from Jarnheim.rpf.race import * -from Jarnheim.rpf.ban import * -from Jarnheim.rpf.character import * -from Jarnheim.rpf.guild import * +from Jarnheim.rpf.models import * admin.site.register(race) admin.site.register(ban) diff --git a/rpf/models.py b/rpf/models.py new file mode 100644 index 0000000..7a8fc37 --- /dev/null +++ b/rpf/models.py @@ -0,0 +1,5 @@ +#from jarnheim.rpf.models import * +from Jarnheim.rpf.race import * +from Jarnheim.rpf.ban import * +from Jarnheim.rpf.character import * +from Jarnheim.rpf.guild import * From e9e49a729296a3bcf1718b2764cdf11de021e0cf Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 15:27:58 -0800 Subject: [PATCH 03/13] Added some extra info to guild --- rpf/guild.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rpf/guild.py b/rpf/guild.py index 2208a86..1b0a645 100644 --- a/rpf/guild.py +++ b/rpf/guild.py @@ -3,7 +3,8 @@ class guild( models.Model ): id = models.AutoField( primary_key = True ) guild_leader_character = models.ForeignKey( 'character' ) - create_dtm = models.DateTimeField() + create_dtm = models.DateTimeField(verbose_name="Date created", + db_index=False) name = models.CharField( max_length = 30 ) @@ -12,4 +13,4 @@ def __unicode__( self ): class Meta: db_table = 'rpf_guild' - app_label= 'rpf' \ No newline at end of file + app_label= 'rpf' From 1174f97d484d8b5acc039bdfe83c680e9393d036 Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 15:28:33 -0800 Subject: [PATCH 04/13] Added some extra race info --- jar.sql | Bin 69632 -> 88064 bytes rpf/race.py | 8 +++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/jar.sql b/jar.sql index 902fa9299d35c458eef90e6a958fe003f0eeda2f..80a5053c047beb2a12108c988d120d56d5ed483b 100644 GIT binary patch delta 2926 zcmcImO>7(25#Gn$L(PX*oq5UPKsXKG{*MQ00Eq!DA1l93vl8DXoDVlG7$6<*id^&Q51F2Lwsm~qD9;H zmgGvbYUET3csnz1-u!$sZ=SB+WUk&~-|_ZdrrLjlH=cR6n}$b3dK&%-e}_jO?z{p0 znDq?c<)jNQ-HsD@4cYD)(7}6{G;@}*(SM*nqkl$Ur89Jt?zVkpySJb0xMHgZLM%0g zM$RegoLW-WmvwG=yIj$n4JL0ggF%)GBOlRGG_9$Csm3lBV5z53@Q8(~qUxPZ1B4Fv zEgza*(Q7Rqn5ko~Vdf0SQW6>?W|~Ua0zO^St6dF2-V%g-EcHzkZUtn?yGT$L=NV?H zAo8}f3d*{J?Bg#t)C#%Ya%RTd^h4<3L6(Xj|B zJYd;srbcX;q~A0)aEhfy&`>KVY>M68PxkzcF}QxV-d4HLNe20l)2dalmq9_)R-307G=iMX%*}H9`x!Kbj)Bg( z7!*eB5c^Ir$ctLA4rA*tWAjH~9O_|^A05GMuwndhh`bHG=1C0CKsSSiP-hE;Q~O;1 zl_^afACHH$aY>gGsy?psnl34l5Yq%zSEJ*SqN<8I9+eBCE+&cyAtB21W4tgX@?11J zA@UP^^sFF@33=SwiE@H4A;u@f*jZT=vHtB>8E(*N|AK-q;U3(Do3I0mkb+U@2fO_* z_AmB(J$LN$PdQo2?Q)xlRX2;~cc6=vMY@g=hCpCS^s9>vAEg7I{^{pvDurUgQ;3 zRP>l8NoqP%DlJX!?bz7aYj1qL_GD#caYfy|_`;m9lv$9{YxplSCtRG&meVg!uckAq znBH9#(vu5yX*M%^DJ{&#W>;QICfE5($(KsmR7Eanx%rKpnB8?O<)({^Yv)%KA-lbF zA$2bMQe{x+(;YMkKeJ6`R(qc z*SLW^FXBcbqc6`li4mM2vlsM%duRwf|KRSw(f;zMVdnN{Oak}qm*hhJ8Y6KR zp8eMUtW{JHq6ynDoh0}E38l0-_L1j5?%SiNr%wNoa#DVZ{xh@0+-F~5|75=ozqL8( zpQDr1Pw>XhX>jvCv==F_Yx*S;x_Qg^d=&=+x#MBYUN5;yVdHj@D^{uUd`H#{lFGU^)4p+Ha zJ30+OU)PTE##byeu3+;4uCTFj40v4Dtqr_a(=XL5+m6WL0P7`?;^T({>;n(?0oU694KJKvN?-q7BjO1o5Eyv0mIFL5-(UcD~Q#2rX(3!ny8o>S{kRM7#SrQ z8zz|>rkW+DBw84nTbL%ACK;L;rzTpaSR@%Fo0~B*G8!2e8tNJv=^7g-7#Uibm|7Vd z>Y13CnHd`4mf4iRq9DS-uED_mko^q%PWA=tW$cmcuIw5>cL=ag)@Z*2l+9vb&tkvJ zzK{J4`+4?->^ovA^b}sflrk6})nWw+d QW-QutfW=}n%Yi@Q0IxP;C;$Ke diff --git a/rpf/race.py b/rpf/race.py index 4f6eeea..6946a82 100644 --- a/rpf/race.py +++ b/rpf/race.py @@ -2,12 +2,14 @@ class race( models.Model ): id = models.AutoField( primary_key = True ) - create_dtm = models.DateTimeField() - name = models.CharField( max_length = 30 ) + create_dtm = models.DateTimeField(verbose_name="Date created", + db_index=False) + name = models.CharField( max_length = 30, + db_index=False) def __unicode__( self ): return self.name class Meta: db_table = 'rpf_race' - app_label= 'rpf' \ No newline at end of file + app_label= 'rpf' From 1b62387189f301375331e78772122642da7662cf Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 16:26:31 -0800 Subject: [PATCH 05/13] Added more user stories. --- requirements/user_stories.txt | 47 ++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/requirements/user_stories.txt b/requirements/user_stories.txt index 176b975..1bf1094 100644 --- a/requirements/user_stories.txt +++ b/requirements/user_stories.txt @@ -13,4 +13,49 @@ User visits guild page to see what the guild is about. User clicks "Join Guild" button. User is directed back to the guild page with a welcome message and member only view. -**User enters a workout** \ No newline at end of file +**User chooses a guild** +User browses the list of guilds. +User finds a guild they want to join. (Are some guilds invite only?) +User clicks "Join Guild" button. +User is directed back to the guild page with a welcome message and member only view. + +**User enters a workout sequence** +User clicks the "Workout sequence" button. +User selects 5/3/1 BBB. +If user has already done the required exercises, 1rm's are automatically calculated. They are otherwise blank. +User has the ability to adjust 1rm numbers. +User has the ability to change assistive work. +User clicks the "Save" button. +User is presented with confirmation that the sequence was saved. + +**User enters a custom workout sequence** +User clicks the "Workout sequence" button. +User selects "Custom". +User gives the sequence a name. +User enters excercises and goal weights/sets/reps if desired. +User can create new workouts in the sequence by clicking the "New Workout" button. +User clicks the "Save" button. +User is presented with confirmation that the sequence was saved. + +**User enters a workout (5/3/1 was set up as a sequence)** +User clicks the "Track" tab/button/link. +The next appropriate 5/3/1 workout is displayed with appropriate weights and reps. +User adjusts weights and reps as needed. +User has the ability to add or delete assistive work and sets of main work. +User clicks the "Save" button. +User is presented with the visual of their workout along with point information. + +**Guild creates a workout sequence** +Guild admin clicks "Create a workout sequence" from within the guild admin page. +Guild admin gives the workout sequence a name. +Guild admin enters exercises, target sets and reps, and target 1rm percentages or actual weights (not recommended because of gender differences). +Guild admin can create different workouts in the sequence by clicking the "New Workout" button. +Guild admin clicks "Save". +Guild admin is presented with save confirmation, along with a visual of what kind of point percentages will be given for that workout sequence. +Workout sequence now appears in the available list for all users in the guild. + +**User enters a stand-alone workout** +User clicks the "Track" button/link/tab. +User selects exercises and enters sets/reps/assisted/weighted/weight/time information. +User clicks the "Save" button. +User is presented with save confirmation and a graphic representing points/percentages and such earned in this workout. \ No newline at end of file From 91114ccb30516db3ba65f3e8d98e994ae4e2a83c Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 20:19:30 -0800 Subject: [PATCH 06/13] Added some formula thoughts --- requirements/formulas.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 requirements/formulas.txt diff --git a/requirements/formulas.txt b/requirements/formulas.txt new file mode 100644 index 0000000..fd5ad51 --- /dev/null +++ b/requirements/formulas.txt @@ -0,0 +1,20 @@ +**Lifts** +Base point value of 100 for 1 rep of 1rm. (Initial time doing this lift means the heaviest lift is the 1rm, the rest will be computed based on that.) +Other lower lifts get point value based on percentage, up to 10 reps. After 10 reps, they get 50% of that point value per rep for another 10 reps, etc. +Maybe 150 points for a new 1rm? +Possibly some kind of level up value for breaking into a different level based on strstd standards? + +**Cardio** +I have no idea how to handle this fairly. New people shouldn't be penalized for running only a mile, but a marathon should obviously be worth more. Maybe get some cardio people's input on how to handle this fairly. + +**HIIT** +I feel like this needs it's own category. Going by distance and speed doesn't make sense for hill sprints and such. Under this category: Prowler push, hill sprint, bike HIIT. + +Again, 100 point baseline for time/distance. Break either of these to get the 50pt 1rm+ type calculation for the session. + +**Bodyweight Work** +This would include yoga and gymnastics. + +Yoga works through a progression, so maybe we could handle this like a complex? A specific hold wouldn't be timed, but you could look at how many times you did a set of positions in a yoga workout. We could use a yoga expert for hold names - some people use the English name and some the ... Sandskrit? ... name. 100pts for a complex, bonus for spending longer on it? Maybe something could be figured out for progression of hold difficulty (crow stand vs hand stand). + +Gymnastics is a little more straightforward - holds for time are easier to figure out. 100pts for doing a hold for the 1rm time, 50pt bonus for going up by ... say ... 30 seconds? \ No newline at end of file From e179cf9063a430431c28c4657913983532ae0d89 Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 21:57:30 -0800 Subject: [PATCH 07/13] Added a formula and some tests --- requirements/formulas.py | 91 ++++++++++++++++++++++++++++++++++++ requirements/testFormulas.py | 36 ++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 requirements/formulas.py create mode 100644 requirements/testFormulas.py diff --git a/requirements/formulas.py b/requirements/formulas.py new file mode 100644 index 0000000..95dd1b5 --- /dev/null +++ b/requirements/formulas.py @@ -0,0 +1,91 @@ +#Percentages from http://www.exrx.net/Calculators/OneRepMax.html + +BRZYCKI = {"1": 100, + "2": 95, + "3": 90, + "4": 88, + "5": 86, + "6": 83, + "7": 80, + "8": 78, + "9": 76, + "10": 75, + "11": 72, + "12": 70} + +BEACHLE = {"1": 100, + "2": 95, + "3": 93, + "4": 90, + "5": 87, + "6": 85, + "7": 83, + "8": 80, + "9": 77, + "10": 75, + "11": 75, + "12": 67, + "13": 65} + +DOSREMEDIOS = {"1": 100, + "2": 92, + "3": 90, + "4": 87, + "5": 85, + "6": 82, + "7": 82, + "8": 75, + "9": 75, + "10": 70, + "11": 70, + "12": 65, + "13": 60} + +maxComputeMethod = BRZYCKI + +def compute1rm(set, old1rm=0): + """Compute the 1rm for this exercise. + + set = iterator of the current set. Needs to have reps and weight + as available variables + old1rm = the current 1rm + + Usage + >>> set = _Set() + >>> set.reps = 4 + >>> set.weight = 100 + >>> compute1rm(set) + 88.0 + + >>> compute1rm(set, 4) + 88.0 + + """ + newMax = old1rm + reps = str(set.reps) + + if set.reps < 1: + #0 reps - return old1rm + return old1rm + elif reps not in maxComputeMethod.keys(): + #Reps are not in the dictionary, return the larger of the + #older max and whatever was done in this set + return max((old1rm, set.weight)) + + thisMax = .01 * set.weight * maxComputeMethod[reps] + + if thisMax > newMax: + newMax = thisMax + + if newMax > 0: + return newMax + else: + return set.weight + +class _Set(object): + reps = 0 + weight = 0 + +if "__main__" == __name__: + import doctest + doctest.testmod() diff --git a/requirements/testFormulas.py b/requirements/testFormulas.py new file mode 100644 index 0000000..369e7b7 --- /dev/null +++ b/requirements/testFormulas.py @@ -0,0 +1,36 @@ +import unittest +from formulas import * + +class Set(object): + reps = 0 + weight = 100 + +class TestCompute1rm(unittest.TestCase): + + def setUp(self): + self.set = Set() + self.set.reps = 1 + self.set.weight = 100 + + def test0reps(self): + self.set.reps = 0 + new1rm = compute1rm(self.set) + self.assertEqual(new1rm, 0, "1rm should be 0 - set was not completed") + newer1rm = compute1rm(self.set, 100) + self.assertEqual(newer1rm, 100, "1rm should remain 100") + + def test1rep(self): + self.set.reps = 1 + new1rm = compute1rm(self.set, 100) + self.assertEqual(new1rm, 100, "1rm should remain 100") + newer1rm = compute1rm(self.set, 99) + self.assertEqual(newer1rm, 100, "1rm should now be 100") + + def testSeveralReps(self): + maxComputedMethod = BRZYCKI + self.set.reps = 2 + twoRepsMax = compute1rm(self.set) + self.assertEqual(twoRepsMax, 95, "1rm should now be 95") + +if "__main__" == __name__: + unittest.main() From 1b633b574c95ea61a2300a4ea2d04c828772b913 Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 22:03:59 -0800 Subject: [PATCH 08/13] Added another sanity check test --- requirements/testFormulas.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/requirements/testFormulas.py b/requirements/testFormulas.py index 369e7b7..87efb30 100644 --- a/requirements/testFormulas.py +++ b/requirements/testFormulas.py @@ -13,6 +13,10 @@ def setUp(self): self.set.weight = 100 def test0reps(self): + """Sanity check: + 0 reps should return whatever the old rep max was. + The set is considered incomplete. + """ self.set.reps = 0 new1rm = compute1rm(self.set) self.assertEqual(new1rm, 0, "1rm should be 0 - set was not completed") @@ -20,6 +24,11 @@ def test0reps(self): self.assertEqual(newer1rm, 100, "1rm should remain 100") def test1rep(self): + """Sanity check: + 1 rep will always change the max to that weight if it's + more than the old 1rm. If it's not, the 1rm remains + unchanged. + """ self.set.reps = 1 new1rm = compute1rm(self.set, 100) self.assertEqual(new1rm, 100, "1rm should remain 100") @@ -27,10 +36,22 @@ def test1rep(self): self.assertEqual(newer1rm, 100, "1rm should now be 100") def testSeveralReps(self): + """Formula check""" maxComputedMethod = BRZYCKI self.set.reps = 2 twoRepsMax = compute1rm(self.set) self.assertEqual(twoRepsMax, 95, "1rm should now be 95") + def testWayTooManyReps(self): + """Sanity check: + Lots of reps means the calculators become fairly useless. + We can go ahead and change the max to whatever was done, + but there's no real value in trying to figure out what the + max would be. + """ + self.set.reps = 200 + twohundredRepsMax = compute1rm(self.set) + self.assertEqual(twohundredRepsMax, 100, "1rm should now be 100") + if "__main__" == __name__: unittest.main() From a3a2b70002d2a47c9484ff2084729ceb5485e243 Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 23:18:53 -0800 Subject: [PATCH 09/13] Added a formula for points --- requirements/formulas.py | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/requirements/formulas.py b/requirements/formulas.py index 95dd1b5..60ff1f1 100644 --- a/requirements/formulas.py +++ b/requirements/formulas.py @@ -75,14 +75,60 @@ def compute1rm(set, old1rm=0): thisMax = .01 * set.weight * maxComputeMethod[reps] if thisMax > newMax: - newMax = thisMax + return thisMax if newMax > 0: return newMax else: return set.weight +def getSetRepValues(reps, points): + """Return rep values for this set. + + Recursive, point values decrease by half for every 10 reps. + + >>> getSetRepValues(1, 10) + 10 + + >>> getSetRepValues(10, 10) + 100 + + >>> getSetRepValues(20, 10) + 150 + + >>> getSetRepValues(30, 10) + 170 + + """ + + if reps > 10: + return points * 10 + getSetRepValues(reps-10, points/2) + else: + return points * reps + +def calculateSetPoints(set, old1rm=0): + """Calculate the points for this set. + """ + pointsEarned = 0 + base1rmPoints = 100 + new1rm = compute1rm(set, old1rm) + + #New 1rm deserves extra points! + if(new1rm > old1rm): + pointsEarned += base1rmPoints/2 + + percentage1rm = set.weight / new1rm + + reps = set.reps + + #First 10 reps get full point value + #Next 10 reps get 50% of that rep value + pointsEarned += getSetRepValues(reps, (percentage1rm * 100)) + + return pointsEarned + class _Set(object): + exercise = 0 reps = 0 weight = 0 From cf4eca46241336982a80b0305ef41bb1bede8d90 Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sat, 31 Dec 2011 23:34:47 -0800 Subject: [PATCH 10/13] Added unittest for set point calculator --- requirements/testFormulas.py | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/requirements/testFormulas.py b/requirements/testFormulas.py index 87efb30..e0e47bf 100644 --- a/requirements/testFormulas.py +++ b/requirements/testFormulas.py @@ -5,6 +5,44 @@ class Set(object): reps = 0 weight = 100 +class TestCalculateSetPoints(unittest.TestCase): + + def setup(self): + self.set = Set() + self.set.reps = 0 + self.set.weight = 100 + + def test0reps(self): + """0 reps should earn 0 points""" + self.set.reps = 0 + points = calculateSetPoints(set, 45) + self.assert(points, 0, "0 points should have been earned") + + def test1reps(self): + """1 rep should earn the full amount""" + self.set.reps = 1 + points = calculateSetPoints(set, 10) + self.assert(points, 10, "10 points should have been earned") + + def test10reps(self): + """10 reps should earn 10xpoints points""" + self.set.reps = 10 + points = calculateSetPoints(set, 10) + self.assert(points, 100, "100 points should have been earned") + + def test20reps(self): + """20 reps should earn 10xpoints + 10xpoints/2 points""" + self.set.reps = 20 + points = calculateSetPoints(set, 10) + self.assert(points, 150, "150 points should have been earned") + + def test30reps(self): + """30 reps should earn 20 reps points + 10xpoints/2/2 + points""" + self.set.reps = 30 + points = calculateSetPoints(set, 10) + self.assert(points, 170, "170 points should have been earned") + class TestCompute1rm(unittest.TestCase): def setUp(self): From 795a2477ac9dee7fe711bbc6b71f2c4e6c03fb9f Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sun, 1 Jan 2012 14:23:41 -0800 Subject: [PATCH 11/13] Added some thoughts on graphics --- requirements/graphics.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 requirements/graphics.txt diff --git a/requirements/graphics.txt b/requirements/graphics.txt new file mode 100644 index 0000000..7f57c2e --- /dev/null +++ b/requirements/graphics.txt @@ -0,0 +1,18 @@ +Levels + +Let's say that we start with a limit of level 10. +This would mean we need 10 pieces of avitar art for male and 10 for female. + +0 Avitar is a scrawny guy/girl in a loincloth or similar, a little hunched over. +1 Avitar gains becomes tone. +2 Avitar gains leather armor and boots. +3 Avitar gains more muscle. +4 Avitar gains a helmet. +5 Avitar stands up straight. +6 Avitar gains a sword. +7 Avitar gains more muscle. +8 Avitar gains a shield. +9 Avitar gains hero stance (like He-Man). +10 Avitar gains a cape. + +We could do something similar for guild levels, maybe with a Viking ship that ends up with fancy shields, a masthead, and sails. \ No newline at end of file From 656a66c962e3a56ceec96b96492bdba4bd809f01 Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sun, 1 Jan 2012 14:27:07 -0800 Subject: [PATCH 12/13] Fixed spelling derp --- requirements/graphics.txt | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/requirements/graphics.txt b/requirements/graphics.txt index 7f57c2e..e655ae2 100644 --- a/requirements/graphics.txt +++ b/requirements/graphics.txt @@ -4,15 +4,15 @@ Let's say that we start with a limit of level 10. This would mean we need 10 pieces of avitar art for male and 10 for female. 0 Avitar is a scrawny guy/girl in a loincloth or similar, a little hunched over. -1 Avitar gains becomes tone. -2 Avitar gains leather armor and boots. -3 Avitar gains more muscle. -4 Avitar gains a helmet. -5 Avitar stands up straight. -6 Avitar gains a sword. -7 Avitar gains more muscle. -8 Avitar gains a shield. -9 Avitar gains hero stance (like He-Man). -10 Avitar gains a cape. +1 Avatar gains becomes tone. +2 Avatar gains leather armor and boots. +3 Avatar gains more muscle. +4 Avatar gains a helmet. +5 Avatar stands up straight. +6 Avatar gains a sword. +7 Avatar gains more muscle. +8 Avatar gains a shield. +9 Avatar gains hero stance (like He-Man). +10 Avatar gains a cape. We could do something similar for guild levels, maybe with a Viking ship that ends up with fancy shields, a masthead, and sails. \ No newline at end of file From ebfe2dc50bd79566d33344a9608a00b868079cd5 Mon Sep 17 00:00:00 2001 From: Liz Dahlstrom Date: Sun, 1 Jan 2012 14:31:24 -0800 Subject: [PATCH 13/13] Added additional badge idea --- requirements/graphics.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements/graphics.txt b/requirements/graphics.txt index e655ae2..524ec9a 100644 --- a/requirements/graphics.txt +++ b/requirements/graphics.txt @@ -15,4 +15,6 @@ This would mean we need 10 pieces of avitar art for male and 10 for female. 9 Avatar gains hero stance (like He-Man). 10 Avatar gains a cape. -We could do something similar for guild levels, maybe with a Viking ship that ends up with fancy shields, a masthead, and sails. \ No newline at end of file +We could do something similar for guild levels, maybe with a Viking ship that ends up with fancy shields, a masthead, and sails. + +We could also have participation badges for people that aren't necessarily progressing very much. Maybe a crow for someone that goes out and does a lot of different things, a bag of goald for someone that participates every few days even if they don't gain many points, etc. \ No newline at end of file