📄 winmain.cpp
字号:
MenuSelect.Blit(192,Num*64+126);
}
// Draw enabled options
App->m_Font.Print("New Game", 0,150,640,0, \
0xFFFFFFFF,DT_CENTER);
if(g_MenuOptions & MENU_BACK)
App->m_Font.Print("Back to Game",0,214,640,0, \
0xFFFFFFFF,DT_CENTER);
if(g_MenuOptions & MENU_LOAD)
App->m_Font.Print("Load Game",0,278,640,0, \
0xFFFFFFFF,DT_CENTER);
if(g_MenuOptions & MENU_SAVE)
App->m_Font.Print("Save Game",0,342,640,0, \
0xFFFFFFFF,DT_CENTER);
App->m_Font.Print("Quit",0,410,640,0,0xFFFFFFFF,DT_CENTER);
App->m_Graphics.EndScene();
}
App->m_Graphics.Display();
}
void cApp::GameFrame(void *Ptr, long Purpose)
{
cApp *App = (cApp*)Ptr;
sCharacter *CharPtr;
BOOL MonstersInLevel;
long TriggerNum;
char Filename[MAX_PATH], Stats[256];
float MaxY;
// Only process frame states
if(Purpose != FRAMEPURPOSE)
return;
// Quit to menu screen if ESCAPE pressed
if(App->m_Keyboard.GetKeyState(KEY_ESC) == TRUE) {
// Setup menu options
g_MenuOptions = MENU_BACK | MENU_SAVE | MENU_LOAD;
// Push main menu state
App->m_StateManager.Push(App->MenuFrame, App);
return;
}
// If teleporting, then handle that first and return
if(App->m_TeleportMap != -1) {
// Free level and process a new one
App->FreeLevel();
App->LoadLevel(App->m_TeleportMap);
App->m_TeleportMap = -1; // Clear out teleport map #
return; // No more processing this frame
}
// Mark no monsters in level
MonstersInLevel = FALSE;
// See if any character are in level. If any monsters,
// flag as such and change their AI to wander if their
// charge is less then 70, follow AI otherwise.
// Also, process whenever a character reaches a route point.
CharPtr = App->m_CharController.GetParentCharacter();
while(CharPtr != NULL) {
// Alter monster's AI based on charge
if(CharPtr->Type == CHAR_MONSTER) {
MonstersInLevel = TRUE;
// Change AI based on charge
if(CharPtr->Charge >= 70.0f) {
CharPtr->AI = CHAR_FOLLOW;
CharPtr->TargetChar = g_PCChar;
CharPtr->Distance = 0.0f;
} else {
CharPtr->AI = CHAR_WANDER;
}
}
// Check if an NPC character has reached last route point
if(CharPtr->Type==CHAR_NPC && CharPtr->AI==CHAR_ROUTE) {
// Was last point reached?
if(App->LastPointReached(CharPtr) == TRUE) {
// Process the route point script for character.
sprintf(Filename,"..\\Data\\EOR%lu.mls", CharPtr->ID);
App->m_Script.Execute(Filename);
// Don't process any more this frame
return;
}
}
// Go to next character
CharPtr = CharPtr->Next;
}
// Handle start of combat stuff
if(MonstersInLevel==TRUE && App->m_MonstersLastFrame==FALSE)
App->StartOfCombat();
// Handle end of combat stuff if combat over
if(MonstersInLevel==FALSE && App->m_MonstersLastFrame==TRUE)
App->EndOfCombat();
// Remember if monsters where in this frame
// And reset player's charge to full if no monsters
if((App->m_MonstersLastFrame = MonstersInLevel) == FALSE)
g_PCChar->Charge = 100.0f;
// Update controllers
App->m_CharController.Update(33);
App->m_SpellController.Update(33);
// Check for triggers and execute script
if((TriggerNum = App->m_Trigger.GetTrigger(g_PCChar->XPos, \
g_PCChar->YPos, \
g_PCChar->ZPos))) {
sprintf(Filename, "..\\Data\\Trig%lu.mls", TriggerNum);
App->m_Script.Execute(Filename);
return; // Don't process any more this frame
}
// Position the camera for the scene
App->m_Graphics.SetCamera(&App->m_Camera);
// Render everything
App->m_Graphics.ClearZBuffer();
if(App->m_Graphics.BeginScene() == TRUE) {
App->RenderFrame(33);
// Render the player's charge bar, but only during combat
if(MonstersInLevel == TRUE) {
D3DXMATRIX matWorld, matView, matProj;
D3DVIEWPORT8 vpScreen;
D3DXVECTOR3 vecPos;
// Get the world, projection, and view transformations
D3DXMatrixIdentity(&matWorld);
App->m_Graphics.GetDeviceCOM()->GetTransform( \
D3DTS_VIEW, &matView);
App->m_Graphics.GetDeviceCOM()->GetTransform( \
D3DTS_PROJECTION, &matProj);
// Get viewport
App->m_Graphics.GetDeviceCOM()->GetViewport(&vpScreen);
// Offset charge bar by character's height
g_PCChar->Object.GetBounds(NULL,NULL,NULL, \
NULL,&MaxY,NULL,NULL);
// Project coordinates to screen
D3DXVec3Project(&vecPos, &D3DXVECTOR3( \
g_PCChar->XPos, \
g_PCChar->YPos + MaxY, \
g_PCChar->ZPos), \
&vpScreen, &matProj, &matView, &matWorld);
// move 4 pixels right before displaying
vecPos.x += 8.0f;
// Display charge bar below player (flash when full)
App->m_Graphics.EnableZBuffer(FALSE);
App->m_Graphics.BeginSprite();
App->m_Options.Blit((long)vecPos.x,(long)vecPos.y, \
0,0,16,4);
if(g_PCChar->Charge >= 100.0f) {
if(timeGetTime() & 1)
App->m_Options.Blit((long)vecPos.x,(long)vecPos.y, \
0,4,16,4);
} else {
App->m_Options.Blit((long)vecPos.x,(long)vecPos.y, \
0,4,(long)(g_PCChar->Charge/100.0f*16.0f),4);
}
App->m_Graphics.EndSprite();
}
// Draw the player's stats at top-left
sprintf(Stats, "%ld / %ld HP\r\n%ld / %ld MP", \
g_PCChar->HealthPoints, g_PCChar->Def.HealthPoints, \
g_PCChar->ManaPoints, g_PCChar->Def.ManaPoints);
App->m_Stats.Render(Stats);
App->m_Graphics.EndScene();
}
App->m_Graphics.Display();
}
void cApp::BarterFrame(void *Ptr, long Purpose)
{
cApp *App = (cApp*)Ptr;
static cCharICS ICS;
sCharItem *ItemPtr, *ScanPtr;
char Text[256];
long Color, Num, Sel;
// Initialize barter data
if(Purpose == INITPURPOSE) {
// Load the ICS to use for bartering
ICS.Load(g_BarterICS);
// Set text
App->m_Header.SetText("Shop");
App->m_Window.SetText("\r\n\nWhat would you like to buy?");
return;
}
// Shutdown resources used in bartering
if(Purpose == SHUTDOWNPURPOSE) {
// Free barter ICS
ICS.Free();
return;
}
// Process a frame of bartering
// Exit bartering if ESCAPE or right mouse button pressed
if(App->m_Keyboard.GetKeyState(KEY_ESC) == TRUE || \
App->m_Mouse.GetButtonState(MOUSE_RBUTTON) == TRUE) {
App->m_Keyboard.SetLock(KEY_ESC, TRUE);
App->m_Mouse.SetLock(MOUSE_RBUTTON, TRUE);
App->m_StateManager.Pop(App);
return;
}
// Determine which item is selected with mouse
if((Sel = App->m_Mouse.GetYPos() - 128) >= 0)
Sel /= 32;
// See if click on item to buy
if(App->m_Mouse.GetButtonState(MOUSE_LBUTTON) == TRUE) {
App->m_Mouse.SetLock(MOUSE_LBUTTON, TRUE);
// See which item was clicked
if(Sel >= 0 && Sel < ICS.GetNumItems()) {
// Get pointer to item
ItemPtr = ICS.GetItem(Sel);
// Make sure PC has enough gold for item
if(g_PCChar->Def.Money >= \
App->m_MIL[ItemPtr->ItemNum].Price) {
// Search for item already in inventory
ScanPtr = g_PCChar->CharICS->GetParentItem();
while(ScanPtr != NULL) {
// Increase quantity if item already in inventory
if(ScanPtr->ItemNum == ItemPtr->ItemNum) {
ScanPtr->Quantity++;
break;
}
// Go to next pointer
ScanPtr = ScanPtr->Next;
}
// Add item to PC's inventory if not already
if(ScanPtr == NULL)
g_PCChar->CharICS->Add(ItemPtr->ItemNum, 1, NULL);
// Deduct price from PC
g_PCChar->Def.Money -= \
App->m_MIL[ItemPtr->ItemNum].Price;
// Play click sound
App->PlaySound(8);
}
}
}
// Render the bartering scene
if(App->m_Graphics.BeginScene() == TRUE) {
App->RenderFrame();
App->m_Window.Render();
App->m_Header.Render();
// Display items to buy
Num = 0;
ItemPtr = ICS.GetParentItem();
while(ItemPtr != NULL) {
// Calculate color to draw based on mouse position
if(Num == Sel)
Color = D3DCOLOR_RGBA(255,255,0,255);
else
Color = D3DCOLOR_RGBA(128,128,128,255);
// Display item name
App->m_Font.Print(App->m_MIL[ItemPtr->ItemNum].Name, \
32, Num*32+128, 0, 0, Color);
// Display item price
sprintf(Text, "$%lu", App->m_MIL[ItemPtr->ItemNum].Price);
App->m_Font.Print(Text, 300, Num*32+128, 0, 0, Color);
// Go down one line
Num++;
// Go to next item
ItemPtr = ItemPtr->Next;
}
// Display character's gold at top-right
sprintf(Text, "Money: $%lu", g_PCChar->Def.Money);
App->m_Font.Print(Text, 320, 32);
App->m_Graphics.EndScene();
}
App->m_Graphics.Display();
}
void cApp::StatusFrame(void *Ptr, long Purpose)
{
cApp *App = (cApp*)Ptr;
sCharItem *ItemPtr;
char Text[256];
long Color, Num, Sel, i;
// Initialize status
if(Purpose == INITPURPOSE) {
// Set text
App->m_Header.SetText("Status");
return;
}
// Return on shutdown purpose
if(Purpose == SHUTDOWNPURPOSE)
return;
// Process a frame of status screen
// Exit screen if ESCAPE or right mouse button pressed
if(App->m_Keyboard.GetKeyState(KEY_ESC) == TRUE || \
App->m_Mouse.GetButtonState(MOUSE_RBUTTON) == TRUE) {
App->m_Keyboard.SetLock(KEY_ESC, TRUE);
App->m_Mouse.SetLock(MOUSE_RBUTTON, TRUE);
App->m_StateManager.Pop(App);
return;
}
// Determine which item is selected with mouse
if((Sel = App->m_Mouse.GetYPos() - 128) >= 0)
Sel /= 32;
// See if click on item to to use/equip
if(App->m_Mouse.GetButtonState(MOUSE_LBUTTON) == TRUE) {
App->m_Mouse.SetLock(MOUSE_LBUTTON, TRUE);
// See which item was clicked
if(Sel >= 0 && Sel < g_PCChar->CharICS->GetNumItems()) {
// Get pointer to item
ItemPtr = g_PCChar->CharICS->GetItem(Sel);
// Determine what to do w/item
switch(App->m_MIL[ItemPtr->ItemNum].Category) {
case WEAPON:
// Equip/Unequip weapon
if(g_PCChar->Def.Weapon == ItemPtr->ItemNum)
App->m_CharController.Equip(g_PCChar, 0, \
WEAPON, FALSE);
else
App->m_CharController.Equip(g_PCChar, \
ItemPtr->ItemNum, \
WEAPON, TRUE);
break;
case ARMOR:
// Equip/Unequip armor
if(g_PCChar->Def.Armor == ItemPtr->ItemNum)
App->m_CharController.Equip(g_PCChar, 0, \
ARMOR, FALSE);
else
App->m_CharController.Equip(g_PCChar, \
ItemPtr->ItemNum, \
ARMOR, TRUE);
break;
case SHIELD:
// Equip/Unequip shield
if(g_PCChar->Def.Shield == ItemPtr->ItemNum)
App->m_CharController.Equip(g_PCChar, 0, \
SHIELD, FALSE);
else
App->m_CharController.Equip(g_PCChar, \
ItemPtr->ItemNum, \
SHIELD, TRUE);
break;
case HEALING:
g_PCChar->HealthPoints += \
App->m_MIL[ItemPtr->ItemNum].Value;
if(g_PCChar->HealthPoints>g_PCChar->Def.HealthPoints)
g_PCChar->HealthPoints=g_PCChar->Def.HealthPoints;
break;
}
// Reduce quantity if flagged as use once
if(CheckItemFlag(App->m_MIL[ItemPtr->ItemNum].Flags, \
USEONCE)) {
if(ItemPtr->Quantity == 1)
g_PCChar->CharICS->Remove(ItemPtr);
else
ItemPtr->Quantity--;
}
// Play click sound
App->PlaySound(8);
}
}
// Render the scene
if(App->m_Graphics.BeginScene() == TRUE) {
App->RenderFrame();
App->m_Window.Render();
App->m_Header.Render();
// Display inventory on left
App->m_Font.Print("Inventory:", 8, 96);
Num = 0;
ItemPtr = g_PCChar->CharICS->GetParentItem();
while(ItemPtr != NULL) {
// Calculate color to draw based on mouse position
if(Num == Sel)
Color = D3DCOLOR_RGBA(255,255,0,255);
else
Color = D3DCOLOR_RGBA(128,128,128,255);
// Display item name w/quantity
sprintf(Text, "%lu x %s", ItemPtr->Quantity, \
App->m_MIL[ItemPtr->ItemNum].Name);
App->m_Font.Print(Text, 32, Num*32+128, 0, 0, Color);
// If item is equipped, then show E next to it
if(g_PCChar->Def.Weapon == ItemPtr->ItemNum || \
g_PCChar->Def.Armor == ItemPtr->ItemNum || \
g_PCChar->Def.Shield == ItemPtr->ItemNum)
App->m_Font.Print("E", 16, Num*32+128);
// Go down one line
Num++;
// Go to next item
ItemPtr = ItemPtr->Next;
}
// Display known spells at right
App->m_Font.Print("Spells:", 300, 220);
for(i=0;i<64;i++) {
if(g_PCChar->Def.MagicSpells[i/32] & (1 << (i & 31))) {
sprintf(Text, "%lu: %s", i+1, \
App->m_SpellController.GetSpell(i)->Name);
App->m_Font.Print(Text, 320, i*32+252);
}
}
// Display character's stats at top-right
App->m_Font.Print("Stats", 300, 32);
sprintf(Text, "%ld / %ld HP", g_PCChar->HealthPoints, \
g_PCChar->Def.HealthPoints);
App->m_Font.Print(Text, 320, 64);
sprintf(Text, "%ld / %ld MP", g_PCChar->ManaPoints, \
g_PCChar->Def.ManaPoints);
App->m_Font.Print(Text, 320, 96);
sprintf(Text, "$ %lu", g_PCChar->Def.Money);
App->m_Font.Print(Text, 320, 128);
sprintf(Text, "Lvl/Exp: %lu / %lu", g_PCChar->Def.Level, \
g_PCChar->Def.Experience);
App->m_Font.Print(Text, 320, 160);
App->m_Graphics.EndScene();
}
App->m_Graphics.Display();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -