Advertisement
Guest User

EOSERV Pet Code Revision 459

a guest
Aug 8th, 2015
529
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.40 KB | None | 0 0
  1. # Character.CPP
  2. In:
  3. Character::Character(std::string name, World *world)
  4.  
  5. Add: (Around line 350)
  6. this->pet = 0;
  7. this->has_pet = false;
  8. this->pet_transfer = false;
  9.  
  10. Now we need to add some new functions:
  11. void Character::KillPet()
  12. {
  13. if(!this->pet)
  14. {
  15. return;
  16. }
  17.  
  18. if(this->has_pet)
  19. {
  20. UTIL_FOREACH(this->pet->map->characters, character)
  21. {
  22. if(character->InRange(this->pet))
  23. {
  24. this->pet->RemoveFromView(character);
  25. }
  26. }
  27. this->has_pet = false;
  28. //this->pet->RemoveFromView(this->player->character);
  29.  
  30.  
  31. this->pet->map->npcs.erase(
  32. std::remove(this->pet->map->npcs.begin(), this->pet->map->npcs.end(), this->pet),
  33. this->pet->map->npcs.end());
  34. }
  35. }
  36. void Character::SpawnPet(int pet)
  37. {
  38. if(!this->map->GetTile(this->x, this->y).Walkable(false))
  39. {
  40. this->StatusMsg("You are unable to summon at this time.");
  41. this->has_pet = false;
  42. return;
  43. }
  44. unsigned char index = this->map->GenerateNPCIndex();
  45.  
  46. if (index > 250)return;
  47.  
  48. this->pet = new NPC(this->map, pet, this->x, this->y, 1, 1, index, true, true);
  49. this->pet->SetOwner(this);
  50. this->map->npcs.push_back(this->pet);
  51. this->pet->Spawn();
  52. }
  53. void Character::PetTransfer()
  54. {
  55. bool pettransfer = false;
  56. bool following = this->pet->following;
  57. bool guarding = this->pet->guarding;
  58. bool attacking = this->pet->attacking;
  59.  
  60. if(this->has_pet && !this->pet_transfer)
  61. {
  62. UTIL_FOREACH(this->pet->map->characters, character)
  63. {
  64. if (character->InRange(this->pet))
  65. {
  66. this->pet->RemoveFromView(character);
  67. }
  68. }
  69. //this->pet->RemoveFromView(this->player->character);
  70. this->pet->map->npcs.erase(
  71. std::remove(this->pet->map->npcs.begin(), this->pet->map->npcs.end(), this->pet),
  72. this->pet->map->npcs.end());
  73. this->has_pet = false;
  74. pettransfer = true;
  75. }
  76.  
  77. if(!this->has_pet && pettransfer == true)
  78. {
  79. unsigned char index = this->map->GenerateNPCIndex();
  80.  
  81. if (index > 250)
  82. {
  83. return;
  84. }
  85. if(!this->map->Walkable(this->x, this->y))
  86. {
  87. this->StatusMsg("Your summon was despawned due to being off-map");
  88. return;
  89. }
  90. this->pet = new NPC(this->map, this->pet->id, this->x, this->y, 1, 1, index, true, true);
  91. this->pet->SetOwner(this);
  92. this->map->npcs.push_back(this->pet);
  93. this->pet->Spawn();
  94. this->has_pet = true;
  95.  
  96. if(following) this->pet->following = true;
  97. else if(attacking) this->pet->attacking = true;
  98. else if(guarding) this->pet->guarding = true;
  99.  
  100. }
  101. }
  102.  
  103. #Character.HPP
  104. In:
  105. class Character : public Command_Source
  106. {
  107. public:
  108.  
  109. Add: (Around Line 170)
  110.  
  111. NPC *pet;
  112. bool has_pet;
  113. bool pet_transfer;
  114.  
  115. void PetTransfer();
  116. void KillPet();
  117. void SpawnPet(int pet);
  118.  
  119.  
  120. #NPC.HPP
  121. In:
  122. class NPC
  123. {
  124. public:
  125.  
  126. Add:
  127. bool pet;
  128. Character *owner;
  129. bool following = false;
  130. bool attacking = false;
  131. bool guarding = false;
  132. NPC *pet_target = 0;
  133.  
  134. void SetOwner(Character *character);
  135. void Pet(NPC *npc);
  136. void PetDamage(NPC *from, int amount, int spell_id = -1);
  137. void WalkXY(int x, int y);
  138. void DirectionNeeded(int x, int y);
  139.  
  140. Then find:
  141. NPC(Map *map, short id, unsigned char x, unsigned char y, unsigned char spawn_type, short spawn_time, unsigned char index, bool temporary = false);
  142.  
  143. and add bool pet = false, Character *owner = 0; in the brackets.
  144. It should look like this:
  145. NPC(Map *map, short id, unsigned char x, unsigned char y, unsigned char spawn_type, short spawn_time, unsigned char index, bool temporary = false, bool pet = false, Character *owner = 0);
  146.  
  147.  
  148. #NPC.CPP
  149. Change:
  150. NPC::NPC(Map *map, short id, unsigned char x, unsigned char y, unsigned char spawn_type, short spawn_time, unsigned char index, bool temporary)
  151.  
  152. To:
  153. NPC::NPC(Map *map, short id, unsigned char x, unsigned char y, unsigned char spawn_type, short spawn_time, unsigned char index, bool temporary, bool pet, Character* owner)
  154.  
  155. Also add this in the function:
  156. this->owner = owner;
  157. this->pet = pet;
  158.  
  159. In NPC::Act() find:
  160. Character *attacker = 0;
  161. unsigned char attacker_distance = static_cast<int>(this->map->world->config["NPCChaseDistance"]);
  162. unsigned short attacker_damage = 0;
  163.  
  164. And add this below it:
  165. if(this->Data().type == ENF::Pet)
  166. {
  167. if(!this->owner)
  168. {
  169. this->Die();
  170. return;
  171. }
  172.  
  173. if(this->owner)
  174. {
  175. if(this->following || (this->guarding && !this->pet_target))
  176. {
  177. int distance_to_owner = util::path_length(this->owner->x, this->owner->y, this->x, this->y);
  178.  
  179. if(distance_to_owner > 2)
  180. {
  181. this->WalkXY(this->owner->x, this->owner->y);
  182. return;
  183. }
  184. if(distance_to_owner > 7)
  185. {
  186. this->owner->PetTransfer();
  187. }
  188. }
  189. else if(this->guarding || this->attacking)
  190. {
  191. if(this->attacking && !this->pet_target)
  192. {
  193. NPC *closest = 0;
  194. unsigned char closest_distance = static_cast<int>(this->map->world->config["NPCChaseDistance"]);
  195.  
  196. UTIL_FOREACH(this->map->npcs, npc)
  197. {
  198. int distance = util::path_length(npc->x, npc->y, this->x, this->y);
  199.  
  200. if (distance < closest_distance)
  201. {
  202. closest = npc;
  203. closest_distance = distance;
  204. }
  205. }
  206. if(closest)
  207. {
  208. this->pet_target = closest;
  209. }
  210. }
  211. if(this->pet_target)
  212. {
  213. if(util::path_length(this->pet_target->x, this->pet_target->y, this->x, this->y < 8))
  214. {
  215. int dist = util::path_length(this->pet_target->x, this->pet_target->y, this->x, this->y);
  216.  
  217. if(dist > 1)
  218. {
  219. WalkXY(this->pet_target->x, this->pet_target->y);
  220. return;
  221. }
  222. else
  223. {
  224. this->DirectionNeeded(this->pet_target->x, this->pet_target->y);
  225.  
  226. // This should be handled when attacking, but what ever.
  227. UTIL_FOREACH(this->map->characters, character)
  228. {
  229. PacketBuilder builder(PACKET_NPC, PACKET_PLAYER, 18);
  230. builder.AddByte(255);
  231. builder.AddChar(this->index);
  232. builder.AddChar(1 + (character->hp == 0));
  233. builder.AddChar(this->direction);
  234. builder.AddShort(0);
  235. builder.AddThree(0);
  236. builder.AddThree(this->pet_target->hp);
  237. builder.AddByte(255);
  238. builder.AddByte(255);
  239.  
  240. if(!character->InRange(this))
  241. {
  242. continue;
  243. }
  244.  
  245. character->Send(builder);
  246. }
  247.  
  248. //
  249. int dmg = util::rand(this->Data().mindam, this->Data().maxdam);
  250. return;
  251. }
  252. }
  253. else
  254. {
  255. this->pet_target = 0;
  256. }
  257. }
  258. }
  259. }
  260. }
  261. Next goto void NPC::Killed(Character *from, int amount, int spell_id)
  262. Under:
  263. this->alive = false;
  264.  
  265. Add:
  266. if(this->pet)
  267. {
  268. this->owner->StatusMsg("Your summon died...");
  269. this->owner->has_pet = 0;
  270. this->owner->pet = 0;
  271. }
  272.  
  273. Now we need to add some functions:
  274. void NPC::Pet(NPC *npc)
  275. {
  276. this->pet = npc;
  277. }
  278.  
  279. void NPC::SetOwner(Character *character)
  280. {
  281. this->owner = character;
  282. }
  283. void NPC::DirectionNeeded(int x, int y)
  284. {
  285. int xdiff = this->x - x;
  286. int ydiff = this->y - y;
  287. int absxdiff = std::abs(xdiff);
  288. int absydiff = std::abs(ydiff);
  289.  
  290. if (absxdiff > absydiff)
  291. {
  292. if (xdiff < 0)
  293. {
  294. this->direction = DIRECTION_RIGHT;
  295. }
  296. else
  297. {
  298. this->direction = DIRECTION_LEFT;
  299. }
  300. }
  301. else
  302. {
  303. if (ydiff < 0)
  304. {
  305. this->direction = DIRECTION_DOWN;
  306. }
  307. else
  308. {
  309. this->direction = DIRECTION_UP;
  310. }
  311. }
  312. }
  313. void NPC::WalkXY(int x, int y)
  314. {
  315. int xdiff = this->x - x;
  316. int ydiff = this->y - y;
  317. int absxdiff = std::abs(xdiff);
  318. int absydiff = std::abs(ydiff);
  319.  
  320. if ((absxdiff == 1 && absydiff == 0) || (absxdiff == 0 && absydiff == 1) || (absxdiff == 0 && absydiff == 0))
  321. {
  322. //this->Attack(attacker);
  323. return;
  324. }
  325. else if (absxdiff > absydiff)
  326. {
  327. if (xdiff < 0)
  328. {
  329. this->direction = DIRECTION_RIGHT;
  330. }
  331. else
  332. {
  333. this->direction = DIRECTION_LEFT;
  334. }
  335. }
  336. else
  337. {
  338. if (ydiff < 0)
  339. {
  340. this->direction = DIRECTION_DOWN;
  341. }
  342. else
  343. {
  344. this->direction = DIRECTION_UP;
  345. }
  346. }
  347. if (!this->Walk(this->direction))
  348. {
  349. this->Walk(static_cast<Direction>(util::rand(0,3)));
  350. }
  351. return;
  352. }
  353. void NPC::PetDamage(NPC *from, int amount, int spell_id)
  354. {
  355. int limitamount = std::min(this->hp, amount);
  356.  
  357. if (this->map->world->config["LimitDamage"])
  358. {
  359. amount = limitamount;
  360. }
  361.  
  362. if (this->Data().type == ENF::Passive || this->Data().type == ENF::Aggressive)
  363. {
  364. this->hp -= amount;
  365. }
  366. else
  367. {
  368. this->hp = 0;
  369. amount = 0;
  370. }
  371.  
  372. if (this->totaldamage + limitamount > this->totaldamage)
  373. this->totaldamage += limitamount;
  374.  
  375. NPC_Opponent *opponent(new NPC_Opponent);
  376. bool found = false;
  377.  
  378. UTIL_FOREACH(this->damagelist, checkopp)
  379. {
  380. if (checkopp->attacker == from->owner)
  381. {
  382. found = true;
  383.  
  384. if (checkopp->damage + limitamount > checkopp->damage)
  385. checkopp->damage += limitamount;
  386.  
  387. checkopp->last_hit = Timer::GetTime();
  388. }
  389. }
  390.  
  391. if (!found)
  392. {
  393. opponent->attacker = from->owner;
  394. opponent->damage = limitamount;
  395. opponent->last_hit = Timer::GetTime();
  396. this->damagelist.push_back(opponent);
  397. opponent->attacker->unregister_npc.push_back(this);
  398. }
  399.  
  400. if (this->hp > 0)
  401. {
  402. PacketBuilder builder(spell_id == -1 ? PACKET_NPC : PACKET_CAST, PACKET_REPLY, 14);
  403.  
  404. if (spell_id != -1)
  405. builder.AddShort(spell_id);
  406.  
  407. builder.AddShort(from->index);
  408. builder.AddChar(from->direction);
  409. builder.AddShort(this->index);
  410. builder.AddThree(amount);
  411. builder.AddShort(util::clamp<int>(double(this->hp) / double(this->Data().hp) * 100.0, 0, 100));
  412.  
  413.  
  414. if (spell_id != -1)
  415. builder.AddShort(from->owner->tp);
  416. else
  417. builder.AddChar(1); // ?
  418.  
  419. UTIL_FOREACH(this->map->characters, character)
  420. {
  421. if (character->InRange(this))
  422. {
  423. character->Send(builder);
  424. }
  425. }
  426. }
  427. else
  428. {
  429. if(this == from->pet_target)
  430. {
  431. from->pet_target = 0;
  432. }
  433. this->Killed(from->owner, amount, spell_id);
  434. }
  435. }
  436.  
  437. #EODATA.HPP
  438. In:
  439. class ENF
  440. {
  441. public:
  442. enum Type
  443. {
  444.  
  445. Add:
  446. Pet
  447.  
  448.  
  449. #MAP.CPP
  450. #Now this you may want to change to your likings:
  451. Find: npc->Damage(from, amount);
  452. In:
  453. void Map::Attack(Character *from, Direction direction)
  454.  
  455. And add this below:
  456.  
  457. if(from->has_pet)
  458. {
  459. if(!from->pet->following && from->pet->pet_target == 0)
  460. {
  461. from->pet->pet_target = npc;
  462. }
  463. }
  464.  
  465. ### SPAWNING
  466. ## For item spawning:
  467. handlers/item.cpp
  468. Find:
  469. switch (item.type)
  470. {
  471. case EIF::Teleport:
  472. {
  473.  
  474. Now add this first inside the brackets:
  475. if(item.scrollmap != 0 && item.scrollx == 252)
  476. {
  477. if(character->has_pet)
  478. {
  479. character->KillPet();
  480. character->has_pet = false;
  481. break;
  482. }
  483. character->SpawnPet(item.scrollmap);
  484. character->has_pet = true;
  485. character->pet->guarding = true;
  486.  
  487. if(item.scrolly == 1)
  488. {
  489. break;
  490. }
  491. }
  492. ## For spawning via spells:
  493. #MAP.CPP
  494. Find:
  495. void Map::SpellSelf(Character *from, unsigned short spell_id)
  496. {
  497.  
  498. Add this below from->tp -= spell.tp;
  499. if(spell.mindam == 123)
  500. {
  501. std::string n_name = this->world->enf->Get(spell.maxdam).name;
  502. if(!from->has_pet)
  503. {
  504. from->SpawnPet(spell.maxdam);
  505. from->has_pet = true;
  506. from->pet->guarding = true;
  507. from->StatusMsg("You summoned a "+n_name+"!");
  508. }
  509. else
  510. {
  511. if(from->pet->id == spell.maxdam)
  512. {
  513. from->StatusMsg("You despawned your "+n_name+"!");
  514. from->KillPet();
  515. from->has_pet = false;
  516. return; // no tp for reclaiming
  517. }
  518. else
  519. {
  520. std::string old_name = this->world->enf->Get(from->pet->id).name;
  521. from->KillPet();
  522. from->SpawnPet(spell.maxdam);
  523. from->has_pet = true;
  524. from->pet->guarding = true;
  525. from->StatusMsg("You replaced your "+old_name+" with a "+n_name);
  526. }
  527. }
  528. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement