123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OTORNADO.CPP
- //Description : Object Tornado
- //Ownership : Gilbert
- #include <OSYS.h>
- #include <OVGA.h>
- #include <OUNIT.h>
- #include <OTORNADO.h>
- #include <OWORLD.h>
- #include <OWEATHER.h>
- #include <math.h>
- #include <OFIRM.h>
- #include <OFIRMA.h>
- #include <OSERES.h>
- #include <OTOWN.h>
- #define M_PI 3.141592654
- #define DAMAGE_POINT_RADIUS 32
- #define TORNADO_SPRITE_ID 12 // Tornado sprite in SPRITE.DBF
- //--------- Begin of function Tornado::init ---------//
- //
- // <short> startX, startY starting location of the tornado
- // <short> lifeTime time (no. of frames) the tornado survive
- //
- void Tornado::init(short startX, short startY, short lifeTime)
- {
- Sprite::init(TORNADO_SPRITE_ID, startX, startY);
- err_when( strcmp("TORNADO", sprite_info->sprite_code ) );
- attack_damage = (float) 2.0 / ATTACK_SLOW_DOWN;
- life_time = lifeTime;
- set_dir(DIR_N);
- cur_action = SPRITE_MOVE; // always moving
- dmg_offset_x = 0;
- dmg_offset_y = 0;
- }
- //----------- End of function Tornado::init -----------//
- //----------- Begin of function Tornado::pre_process ----------//
- void Tornado::pre_process()
- {
- double angle = m.random(32) / 16.0 * M_PI;
- dmg_offset_x = short(DAMAGE_POINT_RADIUS * sin(angle));
- dmg_offset_y = short(DAMAGE_POINT_RADIUS * cos(angle));
- if( --life_time <= 0)
- cur_action = SPRITE_DIE;
- }
- //----------- End of function Tornado::pre_process ----------//
- //--------- Begin of function Tornado::process_move --------//
- void Tornado::process_move()
- {
- int speed = weather.wind_speed() / 6;
- int minSpeed = magic_weather.wind_day > 0 ? 1 : 5;
- if( speed < minSpeed)
- speed = minSpeed;
- if( speed > 10)
- speed = 10;
- double windDir = weather.wind_direct_rad() + (m.random(31)-15)*M_PI/180.0;
- cur_x += short(speed * sin(windDir));
- cur_y -= short(speed * cos(windDir));
- if( ++cur_frame > cur_sprite_move()->frame_count )
- cur_frame = 1;
- // static UCHAR nextFrame[] = { 1,6,1,1,1,1,4 }; // 1->6->4->1 ...
- // cur_frame = nextFrame[cur_frame];
- hit_target();
- }
- //---------- End of function Tornado::process_move ----------//
- //--------- Begin of function Tornado::hit_target --------//
- void Tornado::hit_target()
- {
- //---- check if there is any unit in the target location ----//
- short damageXLoc = damage_x_loc();
- short damageYLoc = damage_y_loc();
- if( damageXLoc < 0 || damageXLoc >= world.max_x_loc ||
- damageYLoc < 0 || damageYLoc >= world.max_y_loc)
- return;
- Location *locPtr = world.get_loc(damageXLoc, damageYLoc);
- Unit *targetUnit;
- if( locPtr->has_unit(UNIT_AIR))
- {
- targetUnit = unit_array[locPtr->unit_recno(UNIT_AIR)];
- targetUnit->hit_points -= 2*attack_damage;
- if( targetUnit->hit_points <= 0)
- targetUnit->hit_points = (float) 0;
- }
- if( locPtr->has_unit(UNIT_LAND))
- {
- targetUnit = unit_array[locPtr->unit_recno(UNIT_LAND)];
- targetUnit->hit_points -= attack_damage;
- if( targetUnit->hit_points <= 0)
- targetUnit->hit_points = (float) 0;
- }
- else if( locPtr->has_unit(UNIT_SEA))
- {
- targetUnit = unit_array[locPtr->unit_recno(UNIT_SEA)];
- targetUnit->hit_points -= attack_damage;
- if( targetUnit->hit_points <= 0)
- targetUnit->hit_points = (float) 0;
- }
- else
- {
- hit_building(); // pass to hit_building to check whether a building is in the location
- }
- hit_plant();
- hit_fire();
- }
- //---------- End of function Tornado::hit_target ----------//
- //------- Begin of function Tornado::hit_building -----//
- // building means firm or town
- //
- void Tornado::hit_building()
- {
- short damageXLoc = damage_x_loc();
- short damageYLoc = damage_y_loc();
- if( damageXLoc < 0 || damageXLoc >= world.max_x_loc ||
- damageYLoc < 0 || damageYLoc >= world.max_y_loc)
- return;
- Location* locPtr = world.get_loc(damageXLoc, damageYLoc);
- // ##### begin Gilbert 30/10 #####//
- if(locPtr->is_firm() )
- // && firm_res[(firmPtr=firm_array[locPtr->firm_recno()])->firm_id]->buildable )
- {
- Firm *firmPtr = firm_array[locPtr->firm_recno()];
- firmPtr->hit_points -= attack_damage*2;
- if( firmPtr->hit_points <= 0)
- {
- firmPtr->hit_points = (float) 0;
- se_res.sound(firmPtr->center_x, firmPtr->center_y, 1,
- 'F', firmPtr->firm_id, "DIE" );
- firm_array.del_firm(locPtr->firm_recno());
- }
- }
- if( locPtr->is_town() )
- {
- Town *townPtr = town_array[locPtr->town_recno()];
- if( (life_time % 30) == 0 )
- townPtr->kill_town_people(0);
- }
- // ##### end Gilbert 30/10 #####//
- }
- //---------- End of function Tornado::hit_building ----------//
- //---------- Begin of function Tornado::hit_plant --------//
- void Tornado::hit_plant()
- {
- short damageXLoc = damage_x_loc();
- short damageYLoc = damage_y_loc();
- if( damageXLoc < 0 || damageXLoc >= world.max_x_loc ||
- damageYLoc < 0 || damageYLoc >= world.max_y_loc)
- return;
- Location *locPtr = world.get_loc(damageXLoc, damageYLoc);
- if(locPtr->is_plant())
- {
- locPtr->remove_plant();
- // ###### begin Gilbert 24/6 ########//
- world.plant_count--;
- // ###### end Gilbert 24/6 ########//
- }
- }
- //---------- End of function Tornado::hit_plant --------//
- //---------- Begin of function Tornado::hit_fire --------//
- void Tornado::hit_fire()
- {
- short damageXLoc = damage_x_loc();
- short damageYLoc = damage_y_loc();
- if( damageXLoc < 0 || damageXLoc >= world.max_x_loc ||
- damageYLoc < 0 || damageYLoc >= world.max_y_loc)
- return;
- Location *locPtr = world.get_loc(damageXLoc, damageYLoc);
- if(locPtr->fire_str() > 0)
- {
- locPtr->set_fire_str(1);
- }
- }
- //---------- End of function Tornado::hit_plant --------//
- #ifdef DEBUG
- //------- Begin of function TornadoArray::operator[] -----//
- Tornado* TornadoArray::operator[](int recNo)
- {
- Tornado* tornadoPtr = (Tornado*) get_ptr(recNo);
- if( !tornadoPtr )
- err.run( "TornadoArray[] is deleted" );
- return tornadoPtr;
- }
- //--------- End of function TornadoArray::operator[] ----//
- #endif
- //--------- Begin of function TornadoArray::TornadoArray ------//
- TornadoArray::TornadoArray(int initArraySize): SpriteArray(initArraySize)
- {
- }
- //--------- End of function TornadoArray::TornadoArray ------//
- //--------- Begin of function TornadoArray::add_tornado ------//
- //
- // <short> startX, startY starting location of the tornado
- // <short> lifeTime time (no. of frames) the tornado survive
- //
- short TornadoArray::add_tornado(int xLoc, int yLoc, short lifeTime)
- {
- Tornado *tornadoPtr = new Tornado;
- tornadoPtr->init(xLoc, yLoc, lifeTime);
- add(tornadoPtr);
- return 1;
- }
- //--------- End of function TornadoArray::add_tornado ------//
- //--------- Begin of function TornadoArray::create_tornado ------//
- //
- // return: <int> recno of the tornado created.
- //
- short TornadoArray::create_tornado()
- {
- Tornado *tornadoPtr = new Tornado;
- add(tornadoPtr);
- return recno();
- }
- //--------- End of function TornadoArray::create_tornado ------//
- //--------- Begin of function TornadoArray::process ---------//
- void TornadoArray::process()
- {
- int i;
- Tornado* tornadoPtr;
- for (i=1; i <=size() ; i++)
- {
- tornadoPtr = (Tornado*)get_ptr(i);
- if( !tornadoPtr)
- continue;
- //-------- system yield ---------//
- if( i%20==1 )
- sys.yield();
- //------- process tornado --------//
- tornadoPtr->pre_process();
- switch(tornadoPtr->cur_action)
- {
- case SPRITE_IDLE:
- case SPRITE_READY_TO_MOVE:
- tornadoPtr->process_idle();
- break;
- case SPRITE_MOVE:
- tornadoPtr->process_move();
- break;
- //### begin alex 7/3 ###//
- case SPRITE_TURN:
- err_here();
- break;
- //#### end alex 7/3 ####//
- case SPRITE_WAIT:
- tornadoPtr->process_wait();
- break;
- case SPRITE_ATTACK:
- tornadoPtr->process_attack();
- break;
- case SPRITE_DIE:
- if( tornadoPtr->process_die() )
- del(i);
- break;
- }
- }
- }
- //----------- End of function TornadoArray::process -----------//
- //--------- Begin of function TornadoArray::draw_dot ---------//
- //
- // Draw 2x2 tiny squares on map window representing the location of the unit ---//
- //
- void TornadoArray::draw_dot()
- {
- char* vgaBufPtr = vga_back.buf_ptr();
- char* writePtr;
- Tornado* tornadoPtr;
- int i, mapX, mapY;
- int vgaBufPitch = vga_back.buf_pitch();
- for(i=1; i <=size() ; i++)
- {
- tornadoPtr = (Tornado*)get_ptr(i);
- if( !tornadoPtr )
- continue;
- mapX = MAP_X1 + tornadoPtr->cur_x_loc();
- mapY = MAP_Y1 + tornadoPtr->cur_y_loc();
- // ####### begin Gilbert 13/11 #########//
- if( mapX < MAP_X1 || mapX > MAP_X2 || mapY < MAP_Y1 || mapY > MAP_Y2 )
- return;
- // ####### end Gilbert 13/11 #########//
- writePtr = vgaBufPtr + mapY*vgaBufPitch + mapX;
- if( mapY > MAP_Y1)
- {
- if( mapX > MAP_X1 && writePtr[-vgaBufPitch-1] != UNEXPLORED_COLOR)
- writePtr[-vgaBufPitch-1] = (char)TORNADO_COLOR2;
- if( writePtr[-vgaBufPitch] != UNEXPLORED_COLOR)
- writePtr[-vgaBufPitch] = (char)TORNADO_COLOR1;
- if( mapX < MAP_X2 && writePtr[-vgaBufPitch+1] != UNEXPLORED_COLOR)
- writePtr[-vgaBufPitch+1] = (char)TORNADO_COLOR2;
- }
- if( mapX > MAP_X1 && writePtr[-1] != UNEXPLORED_COLOR)
- writePtr[-1] = (char)TORNADO_COLOR1;
- if( mapX < MAP_X2 && writePtr[1] != UNEXPLORED_COLOR)
- writePtr[1] = (char)TORNADO_COLOR1;
- if( mapY < MAP_Y2)
- {
- if( mapX > MAP_X1 && writePtr[vgaBufPitch-1] != UNEXPLORED_COLOR)
- writePtr[vgaBufPitch-1] = (char)TORNADO_COLOR2;
- if( writePtr[vgaBufPitch] != UNEXPLORED_COLOR)
- writePtr[vgaBufPitch] = (char)TORNADO_COLOR1;
- if( mapX < MAP_X2 && writePtr[vgaBufPitch+1] != UNEXPLORED_COLOR)
- writePtr[vgaBufPitch+1] = (char)TORNADO_COLOR2;
- }
- }
- }
- //----------- End of function UnitArray::draw_dot -----------//
|