#include "stdafx.h" #include #include #include #include "hch/CHeroHandler.h" #include "hch/CObjectHandler.h" #include "hch/CTownHandler.h" #include "hch/CArtHandler.h" #include "hch/CDefObjInfoHandler.h" //#include "lua.h" //#include "lualib.h" //#include "lauxlib.h" //#include "lobject.h" //#include "lgc.h" //#include "lapi.h" #include "CLua.h" #include "CGameState.h" #include "lib/VCMI_Lib.h" #include "map.h" #include "server/CScriptCallback.h" #include "lib/NetPacks.h" #pragma warning (disable : 4311) #define DEFOS const CGObjectInstance *os = cb->getObj(objid) bool getGlobalFunc(lua_State * L, std::string fname) { //unsigned int hash = lua_calchash(fname.c_str(), fname.size()); //lua_pushhstring(L, hash, fname.c_str(), fname.size()); //lua_gettable(L, LUA_GLOBALSINDEX); //return lua_isfunction(L, -1); return false; } CObjectScript::CObjectScript() { language = ESLan::UNDEF; //std::cout << "Tworze obiekt objectscript "<ID)); //lua_pushinteger(is, (int)os); //if (lua_pcall (is, 1, 0, 0)) //{ // lua_settop(is, 0); // throw new std::exception(("Failed to call "+genFN("newObject",os->ID)+" function in lua script.").c_str()); //} //lua_settop(is, 0); return; } void CLuaObjectScript::onHeroVisit(int objid, int heroID) { //findF(genFN("heroVisit",os->ID)); //lua_pushinteger(is, (int)os); //lua_pushinteger(is, heroID); //if (lua_pcall (is, 2, 0, 0)) //{ // lua_settop(is, 0); // throw new std::exception(("Failed to call "+genFN("heroVisit",os->ID)+" function in lua script.").c_str()); //} //lua_settop(is, 0); } //std::string CLuaObjectScript::hoverText(int objid) //{ // //findF(genFN("hoverText",os->ID)); // //lua_pushinteger(is, (int)os); // //if (lua_pcall (is, 1, 1, 0)) // //{ // // lua_settop(is, 0); // // throw new std::exception(("Failed to call "+genFN("hoverText",os->ID)+" function in lua script.").c_str()); // //} // //std::string ret = lua_tostring(is,1); // //lua_settop(is, 0); // return ""; //} void CVisitableOPH::newObject(int objid) { visitors.insert (std::pair >(objid,std::set())); DEFOS; MetaString hovername; int pom; switch(os->ID) { case 51: pom = 8; break; case 23: pom = 7; break; case 61: pom = 11; break; case 32: pom = 4; break; case 100: pom = 5; break; default: throw new std::exception("Unsupported ID in CVisitableOPH::hoverText"); } hovername << std::pair(3,os->ID) << " " << std::pair(2,pom); cb->setHoverName(objid,&hovername); //int heroID = cb->getSelectedHero(); //if (heroID>=0) //{ //add += ( (visitors[os].find(heroID) == visitors[os].end()) // ? // (VLC->generaltexth->allTexts[353]) //not visited // : // ( VLC->generaltexth->allTexts[352]) ); //visited //} }; void CVisitableOPH::onHeroVisit(int objid, int heroID) { if (visitors.find(objid)!=visitors.end()) { if(visitors[objid].find(heroID)==visitors[objid].end()) { onNAHeroVisit(objid,heroID, false); visitors[objid].insert(heroID); } else { onNAHeroVisit(objid,heroID, true); } } else { throw new std::exception("Skrypt nie zainicjalizowal instancji tego obiektu. :("); } }; void CVisitableOPH::onNAHeroVisit(int objid, int heroID, bool alreadyVisited) { const CGObjectInstance *os = cb->getObj(objid); int w=0, ot=0, vvv=1; switch(os->ID) { case 51: w=0; ot=80; break; case 23: w=1; ot=39; break; case 61: w=2; ot=100; break; case 32: w=3; ot=59; break; case 100: w=4; ot=143; vvv=1000; break; } if (!alreadyVisited) { switch (os->ID) { case 51: case 23: case 61: case 32: { //cb->changePrimSkill(heroID,w,vvv); //std::vector weko; //weko.push_back(new SComponent(SComponent::primskill,w,vvv)); //cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[ot],&weko); //break; } case 100: { //cb->changePrimSkill(heroID,w,vvv); //std::vector weko; //weko.push_back(new SComponent(SComponent::experience,0,vvv)); //cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[ot],&weko); //break; } } } else { ot++; //cb->showInfoDialog(cb->getHeroOwner(heroID),VLC->objh->advobtxt[ot],&std::vector()); } } std::vector CVisitableOPH::yourObjects() { std::vector ret(5); ret.push_back(51); ret.push_back(23); ret.push_back(61); ret.push_back(32); ret.push_back(100); return ret; } void CVisitableOPW::onNAHeroVisit(int objid, int heroID, bool alreadyVisited) { DEFOS; int mid; switch (os->ID) { case 55: mid = 92; break; case 112: mid = 170; break; case 109: mid = 164; break; } if (alreadyVisited) { if (os->ID!=112) mid++; else mid--; InfoWindow iw; iw.player = cb->getHero(heroID)->tempOwner; iw.text << std::pair(11,mid); cb->showInfoDialog(&iw); } else { int type, sub, val; type = 2; switch (os->ID) { case 55: if (rand()%2) { sub = 5; val = 5; } else { sub = 6; val = 500; } break; case 112: mid = 170; sub = (rand() % 5) + 1; val = (rand() % 4) + 3; break; case 109: mid = 164; sub = 6; if(cb->getDate(2)<2) val = 500; else val = 1000; } int player = cb->getHeroOwner(heroID); cb->giveResource(player,sub,val); InfoWindow iw; iw.player = player; iw.components.push_back(Component(type,sub,val,0)); iw.text << std::pair(11,mid); cb->showInfoDialog(&iw); visited[objid] = true; MetaString ms; //set text to "visited" ms << std::pair(3,os->ID) << " " << std::pair(1,352); cb->setHoverName(objid,&ms); } } void CVisitableOPW::newTurn () { if (cb->getDate(1)==1) //first day of week { for (std::map::iterator i = visited.begin(); i != visited.end(); i++) { (*i).second = false; MetaString ms; //set text to "not visited" ms << std::pair(3,cb->getObj(i->first)->ID) << " " << std::pair(1,353); cb->setHoverName(i->first,&ms); } } } void CVisitableOPW::newObject(int objid) { visited.insert(std::pair(objid,false)); DEFOS; MetaString ms; ms << std::pair(3,os->ID) << " " << std::pair(1,visited[objid] ? 352 : 353); cb->setHoverName(objid,&ms); } void CVisitableOPW::onHeroVisit(int objid, int heroID) { if(visited[objid]) onNAHeroVisit(objid,heroID,true); else onNAHeroVisit(objid,heroID,false); } std::vector CVisitableOPW::yourObjects() //returns IDs of objects which are handled by script { std::vector ret(3); ret.push_back(55); //mystical garden ret.push_back(112); //windmill ret.push_back(109); //water wheel return ret; } void CMines::newObject(int objid) { ourObjs.push_back(objid); cb->setOwner(objid,NEUTRAL_PLAYER); DEFOS; MetaString ms; ms << std::pair(3,os->ID); cb->setHoverName(objid,&ms); } void CMines::onHeroVisit(int objid, int heroID) { //TODO: this is code for standard mines, no support for abandoned mine (subId==7) DEFOS; const CGHeroInstance *h = cb->getHero(heroID); if(h->tempOwner == os->tempOwner) return; //TODO: leaving garrison cb->setOwner(objid,h->tempOwner); MetaString ms; ms << std::pair(9,os->subID) << " " << std::pair(6,23+h->tempOwner); cb->setHoverName(objid,&ms); ms.clear(); int vv=1; //amount of resource per turn if (os->subID==0 || os->subID==2) vv++; else if (os->subID==6) vv = 1000; InfoWindow iw; iw.text << std::pair(10,os->subID); iw.player = h->tempOwner; iw.components.push_back(Component(2,os->subID,vv,-1)); cb->showInfoDialog(&iw); } std::vector CMines::yourObjects() { std::vector ret; ret.push_back(53); return ret; } void CMines::newTurn () { const CGObjectInstance * obj; for (unsigned i=0;igetObj(ourObjs[i]); if (obj->tempOwner == NEUTRAL_PLAYER) continue; int vv = 1; if (obj->subID==0 || obj->subID==2) vv++; else if (obj->subID==6) vv = 1000; cb->giveResource(obj->tempOwner,obj->subID,vv); } } void CPickable::newObject(int objid) { cb->setBlockVis(objid,true); MetaString ms; DEFOS; switch (os->ID) { case 79: ms << std::pair(4,os->subID); break; case 5: ms << std::pair(5,os->subID); break; default: ms << std::pair(3,os->ID); break; } cb->setHoverName(objid,&ms); } void CPickable::onHeroVisit(int objid, int heroID) { DEFOS; switch(os->ID) { case 5: { cb->giveHeroArtifact(os->subID,heroID,-1); //TODO: na pozycje break; } case 79: { ////TODO: handle guards (when battles are finished) //CResourceObjInfo * t2 = static_cast(os->info); //int val; //if(t2->amount) // val = t2->amount; //else //{ // switch(os->subID) // { // case 6: // val = 500 + (rand()%6)*100; // break; // case 0: case 2: // val = 6 + (rand()%5); // break; // default: // val = 3 + (rand()%3); // break; // } //} //if(t2->message.length()) // cb->showInfoDialog(cb->getHeroOwner(heroID),t2->message,&std::vector()); //SComponent ccc(SComponent::resource,os->subID,val); //ccc.description = VLC->objh->advobtxt[113]; //boost::algorithm::replace_first(ccc.description,"%s",VLC->objh->restypes[os->subID]); //cb->giveResource(cb->getHeroOwner(heroID),os->subID,val); //cb->showCompInfo(cb->getHeroOwner(heroID),&ccc); break; } case 101: { //if (os->subID) // break; //not OH3 treasure chest //int wyn = rand()%100; //if (wyn<32) //{ // tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000)); // tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500)); //}//1k/0.5k //else if(wyn<64) //{ // tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1500)); // tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1000)); //}//1.5k/1k //else if(wyn<95) //{ // tempStore.push_back(new CSelectableComponent(SComponent::resource,6,2000)); // tempStore.push_back(new CSelectableComponent(SComponent::experience,0,1500)); //}//2k/1.5k //else //{ // if (1/*TODO: backpack is full*/) // { // tempStore.push_back(new CSelectableComponent(SComponent::resource,6,1000)); // tempStore.push_back(new CSelectableComponent(SComponent::experience,0,500)); // } // else // { // //TODO: give treasure artifact // break; // } //}//random treasure artifact, or (if backapack is full) 1k/0.5k //tempStore[1]->ID = heroID; //player = cb->getHeroOwner(heroID); //cb->showSelDialog(player,VLC->objh->advobtxt[146],&tempStore,this); break; } } //VLC->mh->removeObject(os); } void CPickable::chosen(int which) { //switch(tempStore[which]->type) //{ //case SComponent::resource: // cb->giveResource(player,tempStore[which]->subtype,tempStore[which]->val); // break; //case SComponent::experience: // cb->changePrimSkill(tempStore[which]->ID,4,tempStore[which]->val); // break; //default: // throw new std::exception("Unhandled choice"); // //} //for (int i=0;i CPickable::yourObjects() //returns IDs of objects which are handled by script { std::vector ret(3); ret.push_back(79); //resource ret.push_back(5); //artifact ret.push_back(101); //treasure chest / commander stone return ret; } void CTownScript::onHeroVisit(int objid, int heroID) { cb->heroVisitCastle(objid,heroID); } void CTownScript::newObject(int objid) { MetaString ms; const CGTownInstance * n = cb->getTown(objid); ms << n->name << ", " << n->town->name; cb->setHoverName(objid,&ms); } void CTownScript::onHeroLeave(int objid, int heroID) { cb->stopHeroVisitCastle(objid,heroID); } std::vector CTownScript::yourObjects() //returns IDs of objects which are handled by script { std::vector ret(1); ret.push_back(98); //town return ret; } void CHeroScript::newObject(int objid) { cb->setBlockVis(objid,true); MetaString ms; ms << std::pair(1,15); ms.replacements.push_back(cb->getHero(objid)->name); ms.replacements.push_back(cb->getHero(objid)->type->heroClass->name); cb->setHoverName(objid,&ms); } void CHeroScript::onHeroVisit(int objid, int heroID) { //TODO: check for allies const CGHeroInstance *my = cb->getHero(objid), *vis = cb->getHero(objid); if(my->tempOwner == vis->tempOwner) //one of allied cases { //exchange } else { cb->startBattle( &my->army, &vis->army, my->pos, my, vis); } } std::vector CHeroScript::yourObjects() //returns IDs of objects which are handled by script { std::vector ret(1); ret.push_back(34); //hero return ret; } void CMonsterS::newObject(int objid) { //os->blockVisit = true; DEFOS; switch(VLC->creh->creatures[os->subID].level) { case 1: amounts[objid] = rand()%31+20; break; case 2: amounts[objid] = rand()%16+15; break; case 3: amounts[objid] = rand()%16+10; break; case 4: amounts[objid] = rand()%11+10; break; case 5: amounts[objid] = rand()%9+8; break; case 6: amounts[objid] = rand()%8+5; break; case 7: amounts[objid] = rand()%7+3; break; case 8: amounts[objid] = rand()%4+2; break; case 9: amounts[objid] = rand()%3+2; break; case 10: amounts[objid] = rand()%3+1; break; } MetaString ms; int pom = CCreature::getQuantityID(amounts[objid]); pom = 174 + 3*pom + 1; ms << std::pair(6,pom) << " " << std::pair(7,os->subID); cb->setHoverName(objid,&ms); } void CMonsterS::onHeroVisit(int objid, int heroID) { DEFOS; CCreatureSet set; //TODO: zrobic secik w sposob wyrafinowany set.slots[0] = std::pair(os->subID,((CCreatureObjInfo*)os->info)->number); cb->startBattle(heroID,&set,os->pos); } std::vector CMonsterS::yourObjects() //returns IDs of objects which are handled by script { std::vector ret(1); ret.push_back(54); //monster return ret; } void CCreatureGen::newObject(int objid) { DEFOS; amount[objid] = VLC->creh->creatures[VLC->objh->cregens[os->subID]].growth; MetaString ms; ms << std::pair(8,os->subID); cb->setHoverName(objid,&ms); } void CCreatureGen::onHeroVisit(int objid, int heroID) { } std::vector CCreatureGen::yourObjects() //returns IDs of objects which are handled by script { std::vector ret(1); ret.push_back(17); //cregen1 return ret; }