tBool GetRef(int *aRef,tForthHeaderType match1, tForthHeaderType match2) { tBool matched=kFalse; if((matched=CheckRef(match1,match2))) // ref matches, so copy the name. *aRef=gRefStack[gRefSP].iLabelIndex; return matched; }
//============================================================================= bool TryMove(Unit& u, DIR new_dir, bool attack) { u.new_pos = u.pos + dir_change[new_dir]; if(u.new_pos.x >= 0 && u.new_pos.y >= 0 && u.new_pos.x < MAP_W && u.new_pos.y < MAP_H) { Tile& tile = mapa[u.new_pos.x+u.new_pos.y*MAP_W]; if(tile.IsBlocking(u.is_player)) return false; else if(tile.unit) { if(CheckRef(tile.unit) && attack && tile.unit->GetRef().alive) { // attack if(u.attack_timer <= 0.f) { Unit& target = tile.unit->GetRef(); Hit& hit = Add1(hits); hit.pos = target.GetPos(); hit.timer = 0.5f; hit._ref = tile.unit; u.waiting = 0.5f; u.attack_timer = 1.f/u.base->attack_speed; target.hp -= (u.base->attack - target.base->defense); if(target.hp <= 0) { target.alive = false; player->untaxed_gold += target.gold; player->AddExp(target.base->lvl); } } return true; } else return false; } else { if(new_dir == DIR_NE || new_dir == DIR_NW || new_dir == DIR_SE || new_dir == DIR_SW) { if(mapa[u.pos.x+dir_change[new_dir].x+u.pos.y*MAP_W].IsBlocking() && mapa[u.pos.x+(u.pos.y+dir_change[new_dir].y)*MAP_W].IsBlocking()) return false; } u.dir = new_dir; u.moving = true; u.move_progress = 0.f; mapa[u.new_pos.x+u.new_pos.y*MAP_W].unit = u._ref; return true; } } return false; }
//_______________________________________________________________________ int main (int argc, char *argv[]) { int ref; if (argc != 2) usage (argv[0]); CheckMidiShare (argv[0]); ref = MidiGetNamedAppl (argv[1]); if (!CheckRef (ref)) ErrName (argv[0], argv[1]); fprintf (stdout, "%d\n", ref); return 0; }
static bool DoesPBReferenceNode(IParamBlock2* pb, INode* node) { for (int i = 0; i < pb->NumParams(); i++) { ParamID id = pb->IndextoID(i); ParamType2 type = pb->GetParameterType(id); if (type == TYPE_INODE) { if (pb->GetINode(id) == node) return true; } if (type == TYPE_INODE_TAB) { for (int iNode = 0; iNode < pb->Count(id); iNode++) { if (pb->GetINode(id, 0, iNode) == node) return true; } } if (type == TYPE_REFTARG) { ReferenceTarget* targ = pb->GetReferenceTarget(id); bool ret = CheckRef(targ, node); if (ret) return true; } if (type == TYPE_REFTARG_TAB) { for (int iRef = 0; iRef < pb->Count(id); iRef++) { ReferenceTarget* targ = pb->GetReferenceTarget(id, 0, iRef); bool ret = CheckRef(targ, node); if (ret) return true; } } } return false; }
//============================================================================= void Update(float dt) { // selecting unit INT2 tile((cursor_pos.x + cam_pos.x)/32, (cursor_pos.y + cam_pos.y)/32); if(tile.x >= 0 && tile.y >= 0 && tile.x < MAP_W && tile.y < MAP_W && MousePressedRelease(1)) { Tile& t = mapa[tile.x+tile.y*MAP_W]; selected = t.unit; } // sleep button if(player && player->alive && player->inside_building && cursor_pos.x >= 32 && cursor_pos.y >= 700 && cursor_pos.x < 32+16 && cursor_pos.y < 700+16 && MousePressedRelease(1)) { if(player->gold >= 10 && !player->sleeping && player->hp != player->base->hp) { player->gold -= 10; player->sleeping = true; player->sleeping_progress = 0.f; } } // update player if(player && player->alive && player->waiting <= 0.f && !player->moving) { Unit& u = *player; if(player->sleeping) { player->sleeping_progress += dt; if(player->sleeping_progress >= 1.f) { player->hp += 5; player->sleeping_progress = 0.f; if(player->hp >= player->base->hp) { player->hp = player->base->hp; player->sleeping = false; } } } else if(u.inside_building) { // unit inside building, press SPACE to exit if(KeyPressedRelease(SDL_SCANCODE_SPACE) && !mapa[u.pos.x+u.pos.y*MAP_W].unit) { if(!TryMove(u, DIR_S, false)) { if(rand()%2 == 0) { if(!TryMove(u, DIR_SW, false)) { if(TryMove(u, DIR_SE, false)) u.inside_building = false; } else u.inside_building = false; } else { if(!TryMove(u, DIR_SE, false)) { if(TryMove(u, DIR_SW, false)) u.inside_building = false; } else u.inside_building = false; } } else u.inside_building = false; } } else { struct Key1 { SDL_Scancode k1; SDL_Scancode k2; DIR dir; }; const Key1 keys1[] = { SDL_SCANCODE_LEFT, SDL_SCANCODE_KP_4, DIR_W, SDL_SCANCODE_RIGHT, SDL_SCANCODE_KP_6, DIR_E, SDL_SCANCODE_UP, SDL_SCANCODE_KP_8, DIR_N, SDL_SCANCODE_DOWN, SDL_SCANCODE_KP_2, DIR_S }; struct Key2 { SDL_Scancode k1; SDL_Scancode k2; SDL_Scancode k3; DIR dir; }; const Key2 keys2[] = { SDL_SCANCODE_KP_1, SDL_SCANCODE_LEFT, SDL_SCANCODE_DOWN, DIR_SW, SDL_SCANCODE_KP_3, SDL_SCANCODE_RIGHT, SDL_SCANCODE_DOWN, DIR_SE, SDL_SCANCODE_KP_7, SDL_SCANCODE_LEFT, SDL_SCANCODE_UP, DIR_NW, SDL_SCANCODE_KP_9, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, DIR_NE }; for(int i=0; i<4; ++i) { if(KeyDown(keys2[i].k1) || (KeyDown(keys2[i].k2) && KeyDown(keys2[i].k3))) { if(TryMove(u, keys2[i].dir, true)) break; } } if(!u.moving && u.waiting <= 0.f) { for(int i=0; i<4; ++i) { if(KeyDown(keys1[i].k1) || KeyDown(keys1[i].k2)) { if(TryMove(u, keys1[i].dir, true)) break; } } } } } // update ai for(vector<Unit*>::iterator it = units.begin(), end = units.end(); it != end; ++it) { Unit& u = **it; u.attack_timer -= dt; if(u.hp <= 0) { if(&u == player) player = NULL; if(u.moving) mapa[u.new_pos.x+u.new_pos.y*MAP_W].unit = NULL; mapa[u.pos.x+u.pos.y*MAP_W].unit = NULL; delete &u; it = units.erase(it); end = units.end(); if(it == end) break; } else if(u.waiting > 0.f) u.waiting -= dt; else if(u.moving) { u.move_progress += dt*u.base->move_speed; if(u.move_progress >= 1.f) { u.moving = false; mapa[u.pos.x+u.pos.y*MAP_W].unit = NULL; u.pos = u.new_pos; Tile& tile = mapa[u.pos.x+u.pos.y*MAP_W]; if(tile.building) { tile.unit = NULL; u.inside_building = true; if(player->untaxed_gold) { int tax = player->untaxed_gold*TAX/100; player->untaxed_gold -= tax; player->gold += player->untaxed_gold; player->untaxed_gold = 0; } } } } else if(&u != player && player && player->alive && !player->inside_building) { INT2 enemy_pt; int dist = GetClosestPoint(u.pos, *player, enemy_pt); if(dist <= 50) { if(dist <= 15) { // in attack range if(u.attack_timer <= 0.f) { Hit& hit = Add1(hits); hit.pos = player->GetPos(); hit.timer = 0.5f; hit._ref = player->_ref; u.waiting = 0.5f; u.attack_timer = 1.f/u.base->attack_speed; player->hp -= u.base->attack - player->base->defense; if(player->hp <= 0) { player->alive = false; u.gold += (player->gold + player->untaxed_gold); player->gold = 0; player->untaxed_gold = 0; } } } else { DIR dir = GetDir(u.pos, enemy_pt); if(!TryMove(u, dir, false)) { struct SubDir { DIR a, b; }; const SubDir sub_dir[8] = { DIR_SE, DIR_SW, //DIR_S, DIR_W, DIR_S, //DIR_SW, DIR_NW, DIR_SW, //DIR_W, DIR_N, DIR_W, //DIR_NW, DIR_NE, DIR_NW, //DIR_N, DIR_N, DIR_E, //DIR_NE, DIR_SE, DIR_NE, //DIR_E, DIR_S, DIR_E //DIR_SE, }; if(rand()%2 == 0) { if(!TryMove(u, sub_dir[dir].a, false)) TryMove(u, sub_dir[dir].b, false); } else { if(!TryMove(u, sub_dir[dir].b, false)) TryMove(u, sub_dir[dir].a, false); } } } } } } // update hit animations for(vector<Hit>::iterator it = hits.begin(), end = hits.end(); it != end;) { Hit& hit = *it; hit.timer -= dt; if(hit.timer <= 0.f) { if(it+1 == end) { hits.pop_back(); break; } else { std::iter_swap(it, end-1); hits.pop_back(); end = hits.end(); } } else { if(CheckRef(hit._ref)) hit.pos = hit._ref->GetRef().GetPos(); ++it; } } // set camera if(player) { cam_pos = player->GetPos() - SCREEN_SIZE/2; if(cam_pos.x < 0) cam_pos.x = 0; if(cam_pos.y < 0) cam_pos.y = 0; if(cam_pos.x + SCREEN_SIZE.x > MAP_W*32) cam_pos.x = MAP_W*32-SCREEN_SIZE.x; if(cam_pos.y + SCREEN_SIZE.y > MAP_H*32) cam_pos.y = MAP_H*32-SCREEN_SIZE.y; } }
//============================================================================= void Draw() { // clear render SDL_RenderClear(renderer); // viewport SDL_Rect view; view.w = 32*20; view.h = 32*20; view.x = 0; view.y = 0; SDL_RenderSetViewport(renderer, &view); // tiles SDL_Rect r, r4; r4.w = r.w = 32; r4.h = r.h = 32; int start_x = cam_pos.x/32, start_y = cam_pos.y/32, end_x = min((cam_pos.x+SCREEN_SIZE.x)/32+1, MAP_W), end_y = min((cam_pos.y+SCREEN_SIZE.y)/32+1, MAP_H); for(int y=start_y; y<end_y; ++y) { for(int x=start_x; x<end_x; ++x) { r.x = x*32 - cam_pos.x; r.y = y*32 - cam_pos.y; Tile& tile = mapa[x+y*MAP_W]; if(tile.building) { if(tile.building_tile == BT_DOOR) { r4.x = door_offset.x*32; r4.y = door_offset.y*32; } else if(tile.building_tile == BT_WALL) { r4.x = wall_offset.x*32; r4.y = wall_offset.y*32; } else { r4.x = wall_offset.x*32; r4.y = wall_offset.y*32; SDL_RenderCopy(renderer, tBuilding, &r4, &r); const INT2& offset = tile.building->base->offset; r4.x = offset.x*32; r4.y = offset.y*32; } SDL_RenderCopy(renderer, tBuilding, &r4, &r); } else SDL_RenderCopy(renderer, tTiles, &tiles[mapa[x+y*MAP_W].type].rect, &r); } } // unit for(vector<Unit*>::iterator it = units.begin(), end = units.end(); it != end; ++it) { Unit& u = **it; if(u.inside_building) continue; INT2 pos = u.GetPos(); r.x = pos.x-cam_pos.x; r.y = pos.y-cam_pos.y; SDL_Rect rr; rr.w = 32; rr.h = 32; rr.x = u.base->offset.x*32; rr.y = u.base->offset.y*32; SDL_RenderCopy(renderer, tUnit, &rr, &r); // hp bar if(u.hp != u.base->hp) { Uint8 cr, g, b = 0; float hpp = float(u.hp)/u.base->hp; if(hpp <= 0.5f) { float t = hpp*2; cr = lerp(255, 255, t); g = lerp(0, 216, t); } else { float t = (hpp-0.5f)*2; cr = lerp(255, 76, t); g = lerp(216, 255, t); } SDL_SetTextureColorMod(tHpBar, cr, g, b); SDL_Rect r2; r2.w = int(float(u.hp)/u.base->hp*32); if(r2.w <= 0) r2.w = 1; r2.h = 2; r2.x = 0; r2.y = 0; SDL_Rect r3; r3.w = r2.w; r3.h = r2.h; r3.x = r.x; r3.y = r.y; SDL_RenderCopy(renderer, tHpBar, &r2, &r3); } } // attack image for(vector<Hit>::iterator it = hits.begin(), end = hits.end(); it != end; ++it) { r.x = it->pos.x - cam_pos.x; r.y = it->pos.y - cam_pos.y; SDL_RenderCopy(renderer, tHit, NULL, &r); } // selected unit border if(CheckRef(selected)) { INT2 pos = selected->GetRef().GetPos(); r.x = pos.x - cam_pos.x; r.y = pos.y - cam_pos.y; SDL_RenderCopy(renderer, tSelected, NULL, &r); } SDL_RenderSetViewport(renderer, NULL); // text if(player) text[0].Set(player->GetText()); SDL_QueryTexture(text[0].tex, NULL, NULL, &r.w, &r.h); r.x = 32*(MAP_W+1); r.y = 32; SDL_RenderCopy(renderer, text[0].tex, NULL, &r); // selected unit text if(CheckRef(selected)) { text[1].Set(selected->GetRef().GetText()); SDL_QueryTexture(text[1].tex, NULL, NULL, &r.w, &r.h); r.y = 232; SDL_RenderCopy(renderer, text[1].tex, NULL, &r); } // building if(player && player->alive && player->inside_building) { // text text[2].Set(Format("Inside building: %s", inn->base->name)); SDL_QueryTexture(text[2].tex, NULL, NULL, &r.w, &r.h); r.x = 32; r.y = 672; SDL_RenderCopy(renderer, text[2].tex, NULL, &r); // button r.x = 32; r.y = 700; r.w = 16; r.h = 16; r4.x = 0; r4.y = 0; r4.w = 16; r4.h = 16; SDL_RenderCopy(renderer, tButton, &r4, &r); // button text bool draw_text = false; if(cursor_pos.x >= 32 && cursor_pos.y >= 700 && cursor_pos.x < 32+16 && cursor_pos.y < 700+16) { draw_text = true; text[3].Set("Sleep inside inn for 10 gp."); } if(draw_text) { SDL_QueryTexture(text[3].tex, NULL, NULL, &r.w, &r.h); r.x = 32; r.y = 728; SDL_RenderCopy(renderer, text[3].tex, NULL, &r); } } // display render SDL_RenderPresent(renderer); }
bool NFCElementModule::AfterInit() { CheckRef(); return true; }