Właśnie poszukuje 2-3 programistów C++ do wspólnego projektu - a jest nim emulator WoW: Mists of Pandaria, wszystko jest legalne więc chyba zamieszczam zgodnie z regulaminem.
Prace podzielimy na 3 etapy, mianowicie:
- Budowanie game-contentu, czyli pisanie questow, poprawianie spawnu i loot'a z NPC
- Oskryptowanie Spelli
- Poprawki w samym silniku (wątpie że bedą potrzebne), ew. jakieś nasze zmiany
Pracy jest na około 2-3 miesiące licząc na 3 osobowa ekipę. Po tym czasie odpalamy dedyk, zapełniamy lukę, bo takich serwerów jak nasz praktycznie nie ma - no i dzielimy sie dotacjami, po równo. Jeśli ktoś odpadnie w trakcie to zostanie mu wypłacona część dochodów zaraz po starcie serwera.
Szacunkowa liczba graczy na naszym silniku, zakładając że nie będzie on zbyt stabilny na początku, to jakies 2 tys. osób - oczywiście serwer będzie międzynarodowy więc może uda się dobic do 3,5tys graczy. Przełoży to się na około kilkaset dolarów miesięcznie, samego zysku.
Nie zaczynamy od zera, gdyż silnik na ktorym pracujemy jest open-source i znajduje się https://github.com/ProjectSkyfire/SkyFire_5xx . Również posiadam wiekszość plików DB (coordy, loot itp), które wymagają sprawdzenia i poprawek.
Wymagania:
- średnia znajomość c++ (niekoniecznie biegła gdyż i tak korzystamy z wew. funkcji silnika)
- doświadczenie z korzystania z wspólnego repozytorium
- mile widziana znajomość tematyki gry WoW
- wolny czas dwa razy w tygodniu na krótka pogawędkę z całą ekipą na skype
Ekipa (moja poprzednia ekipa sie nieco się sypnęła)
- projectdevcore (zajmuje się protokołem klienta 5.4.0)
- kontownik (czyli ja), skrypty, funkcje w silniku
Szczegóły podam jeśli ktoś będzie chętny. Można pisać na [email protected] lub facebook.com/kontownik ostatecznie skype: kontownik.
Albo w temacie :)
Przykład takiego pseudo-kodu NPC dla średniozaawansowanych - mam nadzieje ze jest czytelny :)
Kod:
/**********************************/
/*****The Disciple's Challenge*****/
/**********************************/
class mob_jaomin_ro : public CreatureScript
{
public :
mob_jaomin_ro() : CreatureScript("mob_jaomin_ro") { }
struct mob_jaomin_roAI : public ScriptedAI
{
public :
mob_jaomin_roAI(Creature* c) : ScriptedAI(c) { Reset(); }
bool bHome;
bool AggroSaid;
bool sitting_state;
bool disciple_defeated;
void Reset()
{
events.Reset();
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 1); //sit
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(false, UNIT_STATE_STUNNED);
bHome = false;
AggroSaid = false;
sitting_state = true;
disciple_defeated = false;
}
void MoveInLineOfSight(Unit* who)
{
if (who && who->GetTypeId() == TYPEID_PLAYER && !AggroSaid) //&& me->IsHostileTo(who) && !AggroSaid)
{
Player* player = who->ToPlayer();
if(player->hasQuest(29409) && player->GetQuestStatus(29409) == QUEST_STATUS_INCOMPLETE && me->IsWithinDistInMap(who, 23.0f))
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
Talk(SAY_AGGRO);
sitting_state = false;
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); //stand
AggroSaid = true;
}
}
}
void EnterCombat(Unit *pWho)
{
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0); // NONE
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0); //stand
if(pWho->GetTypeId() != TYPEID_PLAYER)
{
me->Kill(pWho, false);
EnterEvadeMode();
AggroSaid = false;
bHome = true;
}
ScheduleEvents();
}
void DamageTaken(Unit *attacker, uint32 &amount)
{
if(me->GetHealth() <= amount)
{
amount = 0 ;
me->SetHealth(me->GetMaxHealth()/10);
/*
me->DeleteThreatList();
me->CombatStop(true);
me->AttackStop();
*/
disciple_defeated = true;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetControlled(true, UNIT_STATE_STUNNED);
if(attacker->ToPlayer())
{
if(attacker->ToPlayer()->hasQuest(29409) && attacker->ToPlayer()->GetQuestStatus(29409) == QUEST_STATUS_INCOMPLETE)
{
events.ScheduleEvent(EVENT_DEFEAT_TALKS, 1000);
}
}
}
}
void JustReachedHome() //home-position
{
if (!bHome) //monster not returned
return;
bHome = false;
ScriptedAI::JustReachedHome();
Reset();
}
void UpdateAI(uint32 diff)
{
if (!me->getVictim())
return;
events.Update(diff);
if(me->HasUnitState(UNIT_STATE_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_HAWK :
if(me->getVictim())
{
DoCast(me->getVictim(), SPELL_HAWK, false);
}
events.ScheduleEvent(EVENT_ELEPHANT, 10000);
break ;
case EVENT_ELEPHANT :
if(me->getVictim())
DoCast(me->getVictim(), SPELL_ELEPHANT, false);
events.ScheduleEvent(EVENT_HAWK, 10000);
break;
case EVENT_ROUNDHOUSE :
DoCastAOE(SPELL_ROUNDHOUSE, false);
events.ScheduleEvent(EVENT_ROUNDHOUSE, 5000);
break;
case EVENT_DEFEAT_TALKS :
Talk(SAY_DEFEAT);
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
events.ScheduleEvent(EVENT_RETURN_TO_HOME, 2000);
break;
case EVENT_RETURN_TO_HOME :
if(me->getVictim() && me->getVictim()->GetTypeId() == TYPEID_PLAYER)
{
Player* p = me->getVictim()->ToPlayer();
if(p->hasQuest(29409) && p->GetQuestStatus(29409) == QUEST_STATUS_INCOMPLETE)
{
p->KilledMonsterCredit(me->GetEntry(), 0);
p->SetPhaseMask(16, true); //master shang xi spawned
}
}
me->SetControlled(false, UNIT_STATE_STUNNED);
bHome = true;
EnterEvadeMode(); // bug?
break;
default :
break;
}
}
DoMeleeAttackIfReady();
EnterEvadeIfOutOfCombatArea(diff);
}
private :
EventMap events ;
inline void ScheduleEvents()
{
events.ScheduleEvent(RAND(EVENT_HAWK, EVENT_ELEPHANT), 3000);
events.ScheduleEvent(EVENT_ROUNDHOUSE, 5000);
}
enum Events
{
EVENT_HAWK = 1,
EVENT_ELEPHANT,
EVENT_ROUNDHOUSE,
EVENT_DEFEAT_TALKS,
EVENT_RETURN_TO_HOME
};
enum Spells
{
SPELL_HAWK = 108955,
SPELL_ELEPHANT = 108938,
SPELL_ROUNDHOUSE = 119301
};
enum Says
{
SAY_AGGRO = 0,
SAY_DEFEAT = 1
};
};
CreatureAI* GetAI(Creature *c) const
{
return new mob_jaomin_roAI(c);
}
};
Zakładki