/* * pHatt - PalmOS(TM) Hattrick (http://www.hattrick.org) Manager Assistant * * player.c - PlayerInformation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "phat.h" static Char *agetext; static Char *charactertext; static Char *valuetext; static Char *injurytext; static MemHandle editName; static MemHandle editValue; static MemHandle editAge; static MemHandle editInjury; static MemHandle clownHandle; static Char **playerValues; static Boolean EditedIsNew; static BitmapType *clownBitmap; static WinHandle toolbg; static RectangleType tooltip; static Char *currency; #define MAXCHARACTER 29 void addPlayer(struct player *n) { struct player *p = players; struct player *l = NULL; while ( p ) { l = p; p = p->next; } if ( l ) l->next = n; else players = n; NofPlayers++; } static void changeValues() { Char *temp; if ( FrmGetActiveFormID() != PlayerEditScreen ) return; MemPtrFree(editedPlayer->name); editedPlayer->name = allocName(FldGetTextPtr(getOPtr(Player_Name))); temp = FldGetTextPtr(getOPtr(Player_Age)); editedPlayer->age = ( temp ? StrAToI(temp) : 17 ); temp = FldGetTextPtr(getOPtr(Player_Value)); editedPlayer->value = currencyToKroner( temp ? StrAToI(temp) : 0 ); temp = FldGetTextPtr(getOPtr(Player_Injured)); editedPlayer->injured = ( temp ? StrAToI(temp) : 0 ); } /* Allocate an empty Player-structure */ struct player *NewPlayer() { struct player *p; p = (struct player *) MemPtrNew(sizeof(struct player)); if ( p ) MemSet(p, sizeof(struct player), 0); p->age = 17; return p; } /* Release a Player-structure */ void deletePlayer(struct player **p) { MemPtrFree((*p)->name); MemPtrFree(*p); *p = NULL; } void removePlayer(UInt16 w) { struct player *p, *l; Int8 i; if ( ! w ) { p = players; players = p->next; deletePlayer(&p); NofPlayers--; return; } l = p = players; i = 0; while ( p && i < w ) { l = p; p = p->next; i++; } if ( p ) { l->next = p->next; deletePlayer(&p); NofPlayers--; } if ( prefs.selectedPlayer > NofPlayers ) prefs.selectedPlayer = NofPlayers; } void sortPlayers() { struct player *newList; struct player *oldList; struct player *traverse; struct player *travlast; struct player *temp; struct player *selected; UInt16 i; Boolean found; if ( prefs.orderby == PrefsOrderInsert ) return; oldList = players; newList = NULL; selected = getPlayer(prefs.selectedPlayer); while ( oldList ) { found = false; traverse = newList; travlast = NULL; temp = oldList->next; while ( (! found) && traverse ) { switch ( prefs.orderby ) { case PrefsOrderAge: if ( oldList->age < traverse->age ) { if ( travlast ) travlast->next = oldList; else newList = oldList; oldList->next = traverse; found = true; } break; case PrefsOrderValue: if ( oldList->value < traverse->value ) { if ( travlast ) travlast->next = oldList; else newList = oldList; oldList->next = traverse; found = true; } break; case PrefsOrderName: if ( StrCaselessCompare(oldList->name, traverse->name) < 0) { if ( travlast ) travlast->next = oldList; else newList = oldList; oldList->next = traverse; found = true; } break; default: break; } travlast = traverse; traverse = traverse->next; } if ( ! found ) { if ( travlast ) travlast->next = oldList; else newList = oldList; oldList->next = NULL; } oldList = temp; } players = newList; traverse = players; found = false; i = 0; while ( (! found) && traverse ) { if ( traverse == selected ) { prefs.selectedPlayer = i; found = true; } i++; traverse = traverse->next; } } /* Copys a Player in Memory */ static void copyPlayer(struct player *to, struct player *from) { if ( from->name ) to->name = allocName(from->name); to->age = from->age; to->form = from->form; to->injured = from->injured; to->nice = from->nice; to->wild = from->wild; to->honest = from->honest; to->value = from->value; to->experience = from->experience; to->stamina = from->stamina; to->winging = from->winging; to->goalie = from->goalie; to->defending = from->defending; to->leading = from->leading; to->playmaking = from->playmaking; to->scoring = from->scoring; to->passing = from->passing; to->setting = from->setting; to->speciality = from->speciality; to->transfer = from->transfer; to->changes.form = from->changes.form; to->changes.experience = from->changes.experience; to->changes.stamina = from->changes.stamina; to->changes.winging = from->changes.winging; to->changes.goalie = from->changes.goalie; to->changes.defending = from->changes.defending; to->changes.playmaking = from->changes.playmaking; to->changes.scoring = from->changes.scoring; to->changes.passing = from->changes.passing; to->changes.setting = from->changes.setting; to->changes.value = from->changes.value; } /* Call this to edit a player, -1 means a new player */ void EditPlayer(Int8 player) { EditedIsNew = player < 0; editedPlayer = NewPlayer(); if ( EditedIsNew ) { editedPlayer->name = allocName("Nameless"); FrmGotoForm(PlayerEditScreen); } else { copyPlayer(editedPlayer, getPlayer(player)); FrmGotoForm(prefs.selectedEditPage); } } /* Edit Event Handler */ Boolean PlayerEditEHandler(EventPtr event) { Boolean handled = false; Int16 sel = 0; Int8 maxname; struct player *t; switch (event->eType) { case frmOpenEvent: gpForm = FrmGetActiveForm(); /* We need this, since if anybody changes applications * at this point, the editedPlayer will be deleted and * we can't edit him anymore at the next start */ prefs.selectedScreen = PlayerScreen; /* Set correct Switch to lit */ switch ( FrmGetActiveFormID() ) { case PlayerEditScreen: CtlSetValue(getOPtr(EditPage1Button), 1); SetEditValue(Player_Leadership, Player_Leadership_Trigger, editedPlayer->leading); SetEditValue(Player_Character, Player_Character_Trigger, editedPlayer->nice); SetEditValue(Player_Honesty, Player_Honesty_Trigger, editedPlayer->honest); SetEditValue(Player_Agress, Player_Agress_Trigger, editedPlayer->wild); editValue = MemHandleNew(maxStrIToALen + 2); valuetext = MemHandleLock(editValue); StrPrintF(valuetext, "%li", valueInCurrency(editedPlayer->value)); FldSetTextHandle(getOPtr(Player_Value), editValue); editAge = MemHandleNew(5); agetext = MemHandleLock(editAge); StrPrintF(agetext, "%i", editedPlayer->age); FldSetTextHandle(getOPtr(Player_Age), editAge); editInjury = MemHandleNew(3); injurytext = MemHandleLock(editInjury); StrPrintF(injurytext, "%i", editedPlayer->injured); FldSetTextHandle(getOPtr(Player_Injured), editInjury); if ( editedPlayer->name && StrLen(editedPlayer->name) > 38) maxname = StrLen(editedPlayer->name + 2); else maxname = 40; editName = MemHandleNew(maxname); charactertext = MemHandleLock(editName); if (editedPlayer->name) StrPrintF(charactertext, "%s", editedPlayer->name); else StrPrintF(charactertext, "%s", "Nameless"); FldSetTextHandle(getOPtr(Player_Name), editName); if (EditedIsNew) { FldSetSelection(getOPtr(Player_Name), 0, 8); FrmSetFocus(gpForm, FrmGetObjectIndex(gpForm, Player_Name)); GrfSetState(false, false, true); GsiSetShiftState(glfCapsLock, 3); } currency = getCurrency(); FldSetTextPtr(getOPtr(Prefs_Currency), currency); break; case PlayerEditScreen2: CtlSetValue(getOPtr(EditPage2Button), 1); SetEditValue(Player_Experience, Player_Experience_Trigger, editedPlayer->experience); SetEditValue(Player_Stamina, Player_Stamina_Trigger, editedPlayer->stamina); SetEditValue(Player_Playmaking, Player_Playmaking_Trigger, editedPlayer->playmaking); SetEditValue(Player_Winging, Player_Winging_Trigger, editedPlayer->winging); SetEditValue(Player_Scoring, Player_Scoring_Trigger, editedPlayer->scoring); FldSetTextPtr(getOPtr(Player_Name), editedPlayer->name); break; case PlayerEditScreen3: CtlSetValue(getOPtr(EditPage3Button), 1); SetEditValue(Player_Form, Player_Form_Trigger, editedPlayer->form); SetEditValue(Player_Goaltending, Player_Goaltending_Trigger, editedPlayer->goalie); SetEditValue(Player_Passing, Player_Passing_Trigger, editedPlayer->passing); SetEditValue(Player_Defending, Player_Defending_Trigger, editedPlayer->defending); SetEditValue(Player_Set_Pieces, Player_Set_Pieces_Trigger, editedPlayer->setting); SetEditValue(Player_Speciality, Player_Speciality_Trigger, editedPlayer->speciality); FldSetTextPtr(getOPtr(Player_Name), editedPlayer->name); break; default: break; } FrmDrawForm(gpForm); if ( firstStart && showWelcome ) { FrmAlert(WelcomeAlert); showWelcome = false; } handled = true; break; case frmCloseEvent: if ( FrmGetActiveFormID() == PlayerEditScreen ) { FldSetTextHandle(getOPtr(Player_Name), NULL); MemHandleUnlock(editName); MemHandleFree(editName); charactertext = NULL; FldSetTextHandle(getOPtr(Player_Age), NULL); MemHandleUnlock(editAge); MemHandleFree(editAge); valuetext = NULL; FldSetTextHandle(getOPtr(Player_Value), NULL); MemHandleUnlock(editValue); MemHandleFree(editValue); agetext = NULL; FldSetTextHandle(getOPtr(Player_Injured), NULL); MemHandleUnlock(editInjury); MemHandleFree(editInjury); injurytext = NULL; } sortPlayers(); FrmEraseForm(gpForm); FrmDeleteForm(gpForm); gpForm = 0; handled = true; break; case ctlSelectEvent: /* We can always change them, since the player will be * deleted anyway, if anybody should hit "Cancel" */ changeValues(); switch (event->data.ctlEnter.controlID) { case EditPage1Button: prefs.selectedEditPage = PlayerEditScreen; FrmGotoForm(PlayerEditScreen); handled = true; break; case EditPage2Button: prefs.selectedEditPage = PlayerEditScreen2; FrmGotoForm(PlayerEditScreen2); handled = true; break; case EditPage3Button: prefs.selectedEditPage = PlayerEditScreen3; FrmGotoForm(PlayerEditScreen3); handled = true; break; case EditOKButton: if ( EditedIsNew ) { addPlayer(NewPlayer()); prefs.selectedPlayer = NofPlayers - 1; } t = getPlayer(prefs.selectedPlayer); if (t->name) MemPtrFree(t->name); copyPlayer(t, editedPlayer); deletePlayer(&editedPlayer); FrmGotoForm(PlayerScreen); handled = true; break; case EditCancelButton: if ( firstStart ) FrmAlert(FirstStartAlert); else { deletePlayer(&editedPlayer); FrmGotoForm(PlayerScreen); } handled = true; break; } break; case popSelectEvent: sel = LstGetSelection(getOPtr(event->data.popSelect.listID)); switch (event->data.popSelect.listID) { case Player_Form: editedPlayer->form = sel; break; case Player_Character: editedPlayer->nice = sel; break; case Player_Honesty: editedPlayer->honest = sel; break; case Player_Agress: editedPlayer->wild = sel; break; case Player_Experience: editedPlayer->experience = sel; break; case Player_Leadership: editedPlayer->leading = sel; break; case Player_Stamina: editedPlayer->stamina = sel; break; case Player_Goaltending: editedPlayer->goalie = sel; break; case Player_Playmaking: editedPlayer->playmaking = sel; break; case Player_Passing: editedPlayer->passing = sel; break; case Player_Winging: editedPlayer->winging = sel; break; case Player_Defending: editedPlayer->defending = sel; break; case Player_Scoring: editedPlayer->scoring = sel; break; case Player_Set_Pieces: editedPlayer->setting = sel; break; case Player_Speciality: editedPlayer->speciality = sel; break; default: break; } default: break; } return handled; } /* Character Helper function */ static Char *getCharacter(Int8 t, Int8 s) { switch ( t ) { case 0: switch ( s ) { case 0: return "nasty"; case 1: return "controversial"; case 2: return "pleasant"; case 3: return "sympathetic"; case 4: return "popular"; case 5: return "beloved"; default: return "unknown"; } case 1: switch ( s ) { case 0: return "tranquil"; case 1: return "calm"; case 2: return "balanced"; case 3: return "temparamental"; case 4: return "fiery"; case 5: return "unstable"; default: return "unknown"; } case 2: switch ( s ) { case 0: return "infamous"; case 1: return "dishonest"; case 2: return "honest"; case 3: return "upright"; case 4: return "righteous"; case 5: return "saint like"; default: return "unknown"; } default: return "unknown"; } } /* Helper for Strings */ static Char *getSpecText(Int8 s) { switch (s) { case 1: return "[Technical]"; case 2: return "[Quick]"; case 3: return "[Powerful]"; case 4: return "[Head]"; case 5: return "[Unpredictable]"; } return ""; } static Boolean hasChanges(struct player *p) { return p->changes.form || p->changes.experience || p->changes.stamina || p->changes.winging || p->changes.goalie || p->changes.defending || p->changes.playmaking || p->changes.scoring || p->changes.passing || p->changes.setting || p->changes.value; } /* Fill Values in */ void ShowValues(struct player *p) { Int8 i, j; RectangleType cArea; Char *value; Char *charac[3], *c; if ( agetext ) MemPtrFree(agetext); if ( charactertext ) MemPtrFree(charactertext); if ( valuetext ) MemPtrFree(valuetext); if ( playerValues ) { for ( i = 0 ; i < 10 ; i++ ) MemPtrFree(playerValues[i]); MemPtrFree(playerValues); } agetext = MemPtrNew(100); charactertext = MemPtrNew(100); valuetext = MemPtrNew(100); if ( p->injured ) StrPrintF(agetext, "%i, %s form, injured (+%i)", p->age, getStrength(p->form), p->injured); else StrPrintF(agetext, "%i, %s form, healthy", p->age, getStrength(p->form)); FldSetTextPtr(getOPtr(Player_Age), agetext); FrmGetObjectBounds(gpForm, FrmGetObjectIndex(gpForm, Player_Character), &cArea); for ( i = 0; i < 3; i++ ) charac[i] = MemPtrNew(30); StrCopy(charac[0], getCharacter(0, p->nice)); StrCopy(charac[1], getCharacter(1, p->wild)); StrCopy(charac[2], getCharacter(2, p->honest)); StrPrintF(charactertext, "%s, %s, %s", charac[0], charac[1], charac[2]); j = 0; while ( FldCalcFieldHeight(charactertext, cArea.extent.x) > 1 ) { c = charac[j]; for ( i = 0; i < (StrLen(charac[j]) - 2) ; i++ ) c++; *c = '.'; c++; *c = '\0'; StrPrintF(charactertext, "%s, %s, %s", charac[0], charac[1], charac[2]); if ( ++j == 3 ) j = 0; } FldSetTextPtr(getOPtr(Player_Character), charactertext); for ( i = 0; i < 3; i++ ) MemPtrFree(charac[i]); value = getInCurrency(p->value, false); StrPrintF(valuetext, "%s %s", value, getSpecText(p->speciality)); MemPtrFree(value); FldSetTextPtr(getOPtr(Player_Value), valuetext); playerValues = MemPtrNew(10 * sizeof(Char *)); for ( i = 0 ; i < 10 ; i++ ) playerValues[i] = MemPtrNew(maxStrIToALen); fillField(playerValues[0], Player_Experience, p->experience); fillField(playerValues[1], Player_Leadership, p->leading); fillField(playerValues[2], Player_Stamina, p->stamina); fillField(playerValues[3], Player_Goaltending, p->goalie); fillField(playerValues[4], Player_Playmaking, p->playmaking); fillField(playerValues[5], Player_Passing, p->passing); fillField(playerValues[6], Player_Winging, p->winging); fillField(playerValues[7], Player_Defending, p->defending); fillField(playerValues[8], Player_Scoring, p->scoring); fillField(playerValues[9], Player_Set_Pieces, p->setting); FrmDrawForm(gpForm); cArea.topLeft.x = 149; cArea.topLeft.y = 0; cArea.extent.x = 11; cArea.extent.y = 11; WinEraseRectangle(&cArea, 0); if ( p->leading == 6 ) { switch ( p->nice) { case 4: clownHandle = DmGetResource(bitmapRsc, Bitmap_Clown); break; case 3: clownHandle = DmGetResource(bitmapRsc, Bitmap_SemiClown); break; default: clownHandle = DmGetResource(bitmapRsc, Bitmap_AntiClown); break; } clownBitmap = MemHandleLock(clownHandle); WinDrawBitmap(clownBitmap, 149, 0); } cArea.topLeft.x = 138; WinEraseRectangle(&cArea, 0); if ( hasChanges(p) ) WinDrawBitmap(starBitmap, 138, 3); } /* Player-Screen Event Handler */ Boolean PlayerScreenEHandler(EventPtr event) { Boolean handled = false; Boolean showTooltip; Int8 i; UInt16 error; Char *c; switch (event->eType) { case frmOpenEvent: gpForm = FrmGetActiveForm(); if ( bgForm ) { FrmEraseForm(bgForm); FrmDeleteForm(bgForm); } bgForm = NULL; updatePlayerList(); agetext = charactertext = valuetext = NULL; playerValues = NULL; clownBitmap = NULL; ShowValues(getPlayer(prefs.selectedPlayer)); toolbg = NULL; handled = true; break; case frmCloseEvent: MemPtrFree(agetext); MemPtrFree(charactertext); MemPtrFree(valuetext); for ( i = 0; i < 10 ; i++ ) MemPtrFree(playerValues[i]); MemPtrFree(playerValues); agetext = charactertext = valuetext = NULL; playerValues = NULL; if ( clownBitmap ) { MemHandleUnlock(clownHandle); clownBitmap = NULL; } if ( toolbg ) { WinRestoreBits(toolbg, tooltip.topLeft.x, tooltip.topLeft.y); toolbg = NULL; } if ( ! bgForm ) { FrmEraseForm(gpForm); FrmDeleteForm(gpForm); } gpForm = 0; handled = true; break; case fldEnterEvent: showTooltip = true; switch (event->data.fldEnter.fieldID) { case Player_Experience: i = getPlayer(prefs.selectedPlayer)->experience; break; case Player_Leadership: i = getPlayer(prefs.selectedPlayer)->leading; break; case Player_Stamina: i = getPlayer(prefs.selectedPlayer)->stamina; break; case Player_Goaltending: i = getPlayer(prefs.selectedPlayer)->goalie; break; case Player_Playmaking: i = getPlayer(prefs.selectedPlayer)->playmaking; break; case Player_Passing: i = getPlayer(prefs.selectedPlayer)->passing; break; case Player_Winging: i = getPlayer(prefs.selectedPlayer)->winging; break; case Player_Defending: i = getPlayer(prefs.selectedPlayer)->defending; break; case Player_Scoring: i = getPlayer(prefs.selectedPlayer)->scoring; break; case Player_Set_Pieces: i = getPlayer(prefs.selectedPlayer)->setting; break; default: showTooltip = false; break; } if ( showTooltip ) { c = getStrength(i); FldGetBounds(getOPtr(event->data.fldEnter.fieldID), &tooltip); error = FntCharsWidth(c, StrLen(c)); tooltip.topLeft.x = tooltip.topLeft.x + tooltip.extent.x - error - 2; tooltip.topLeft.y = tooltip.topLeft.y; tooltip.extent.x = error + 5; tooltip.extent.y = 14; toolbg = WinSaveBits(&tooltip, &error); WinEraseRectangle(&tooltip, 0); tooltip.topLeft.x++; tooltip.topLeft.y++; tooltip.extent.x -= 2; tooltip.extent.y -= 2; WinDrawRectangleFrame(simpleFrame, &tooltip); WinPaintChars(c, StrLen(c), tooltip.topLeft.x + 2, tooltip.topLeft.y); tooltip.topLeft.x--; tooltip.topLeft.y--; tooltip.extent.x += 2; tooltip.extent.y += 2; handled = true; break; } break; case ctlSelectEvent: switch (event->data.ctlEnter.controlID) { case PlayerNewButton: EditPlayer(-1); handled = true; break; case PlayerEditButton: EditPlayer(prefs.selectedPlayer); handled = true; break; case PlayerPosButton: case PositionPlayerButton: FrmGotoForm(whichPositionPage()); handled = true; break; case PlayerClockButton: bgForm = gpForm; FrmGotoForm(TransferScreen); break; } break; case popSelectEvent: switch (event->data.popSelect.listID) { case PlayerSelection: prefs.selectedPlayer = LstGetSelection(getOPtr(PlayerSelection)); ShowValues(getPlayer(prefs.selectedPlayer)); break; default: break; } break; case penDownEvent: if ( toolbg ) { WinRestoreBits(toolbg, tooltip.topLeft.x, tooltip.topLeft.y); toolbg = NULL; // handled = true; } break; case penUpEvent: if ( event->data.penUp.start.x >= 138 && event->data.penUp.start.x <= 149 && event->data.penUp.start.y < 12 && event->data.penUp.end.x >= 138 && event->data.penUp.end.x <= 149 && event->data.penUp.end.y < 12 && hasChanges(getPlayer(prefs.selectedPlayer)) ) { bgForm = gpForm; prefs.prefsPrevScreen = PlayerScreen; FrmGotoForm(ChangesScreen); handled = true; } break; case menuEvent: handled = switchScreen(event->data.menu.itemID); break; default: break; } return handled; }