void actWallBuilder(Entity *my) { int c; if( !my->skill[28] ) return; // received on signal if( my->skill[28] == 2) { playSoundEntity( my, 182, 64 ); Uint16 x = std::min<Uint16>(std::max(0.0,my->x/16),map.width-1); Uint16 y = std::min<Uint16>(std::max(0.0,my->y/16),map.height-1); map.tiles[OBSTACLELAYER+y*MAPLAYERS+x*MAPLAYERS*map.height] = map.tiles[y*MAPLAYERS+x*MAPLAYERS*map.height]; if( multiplayer==SERVER ) { for( c=0; c<MAXPLAYERS; c++ ) { if( client_disconnected[c]==TRUE ) continue; strcpy((char *)net_packet->data,"WALC"); SDLNet_Write16(x,&net_packet->data[4]); SDLNet_Write16(y,&net_packet->data[6]); net_packet->address.host = net_clients[c-1].host; net_packet->address.port = net_clients[c-1].port; net_packet->len = 8; sendPacketSafe(net_sock, -1, net_packet, c-1); } } list_RemoveNode(my->mynode); } }
void spell_changeHealth(Entity* entity, int amount) { if (!entity) { return; } entity->modHP(amount); int player = -1; int i = 0; for (i = 0; i < MAXPLAYERS; ++i) { if (entity == players[i]->entity) { player = i; } } if (player > -1 && player < MAXPLAYERS) { if (amount > 0) { Uint32 color = SDL_MapRGB(mainsurface->format, 0, 255, 0); messagePlayerColor(player, color, language[443]); } else { Uint32 color = SDL_MapRGB(mainsurface->format, 255, 255, 0); if (amount == 0) { messagePlayerColor(player, color, language[444]); } else { messagePlayerColor(player, color, language[445]); } } if (multiplayer == SERVER) { strcpy((char*)net_packet->data, "UPHP"); SDLNet_Write32((Uint32)stats[player]->HP, &net_packet->data[4]); SDLNet_Write32(0, &net_packet->data[8]); net_packet->address.host = net_clients[player - 1].host; net_packet->address.port = net_clients[player - 1].port; net_packet->len = 12; sendPacketSafe(net_sock, net_packet->channel, net_packet, player - 1); } } }
void actFountain(Entity *my) { Entity *entity; //messagePlayer(0, "actFountain()"); //TODO: Temporary mechanism testing code. /* if( multiplayer != CLIENT ) { if (my->skill[28]) { //All it does is change its sprite to sink if it's powered. if (my->skill[28] == 1) { my->sprite = 163; } else { my->sprite = 164; } } }*/ //****************END TEST CODE*************** //TODO: Sounds. // spray water if( my->skill[0] > 0 || ( !my->skill[2] && multiplayer == CLIENT ) ) { #define FOUNTAIN_AMBIENCE my->skill[7] FOUNTAIN_AMBIENCE--; if( FOUNTAIN_AMBIENCE<=0 ) { FOUNTAIN_AMBIENCE = TICKS_PER_SECOND*6; playSoundEntityLocal(my, 135, 32 ); } entity = spawnGib(my); entity->flags[INVISIBLE] = FALSE; entity->y -= 2; entity->z -= 8; entity->flags[SPRITE] = FALSE; entity->flags[NOUPDATE] = TRUE; entity->flags[UPDATENEEDED] = FALSE; entity->skill[4] = 7; entity->sprite = 4; entity->yaw = (rand()%360)*PI/180.0; entity->pitch = (rand()%360)*PI/180.0; entity->roll = (rand()%360)*PI/180.0; entity->vel_x = 0; entity->vel_y = 0; entity->vel_z = .25; entity->fskill[3] = 0.03; } // the rest of the function is server-side. if( multiplayer==CLIENT ) return; // makes the fountain stop spraying water on clients if( my->skill[0] <= 0 ) my->skill[2] = 1; else my->skill[2] = 0; //Using the fountain (TODO: Monsters using it?). int i; for (i = 0; i < MAXPLAYERS; ++i) { if ( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) { if (inrange[i]) { //Act on it only if the player (or monster, if/when this is changed to support monster interaction?) is in range. //First check that it's not depleted. if (my->skill[0] == 0) { //Depleted messagePlayer(i, language[467]); } else { if (players[i]->entity->flags[BURNING]) { messagePlayer(i, language[468]); players[i]->entity->flags[BURNING] = FALSE; if (i > 0) serverUpdateEntityFlag(players[i]->entity, BURNING); } switch (my->skill[1]) { case 0: { playSoundEntity(players[i]->entity, 52, 64); //Spawn succubus. Uint32 color = SDL_MapRGB(mainsurface->format,255,128,0); messagePlayerColor(i, color, language[469]); summonMonster(SUCCUBUS, my->x, my->y); break; } case 1: messagePlayer(i, language[470]); messagePlayer(i, language[471]); playSoundEntity(players[i]->entity, 52, 64); stats[i]->HUNGER += 50; break; case 2: { //Potion effect. Potion effect is stored in my->skill[3], randomly chosen when the fountain is created. messagePlayer(i, language[470]); Item *item = newItem(static_cast<ItemType>(POTION_WATER+my->skill[3]), static_cast<Status>(4), 0,1,0,FALSE,NULL); useItem(item,i); // Long live the mystical fountain of TODO. break; } case 3: { // bless equipment playSoundEntity(players[i]->entity, 52, 64); Uint32 textcolor = SDL_MapRGB(mainsurface->format,0,255,255); messagePlayerColor(i, textcolor, language[471]); messagePlayer(i, language[473]); if( stats[i]->helmet ) stats[i]->helmet->beatitude++; if( stats[i]->breastplate ) stats[i]->breastplate->beatitude++; if( stats[i]->gloves ) stats[i]->gloves->beatitude++; if( stats[i]->shoes ) stats[i]->shoes->beatitude++; if( stats[i]->shield ) stats[i]->shield->beatitude++; if( stats[i]->weapon ) stats[i]->weapon->beatitude++; if( stats[i]->cloak ) stats[i]->cloak->beatitude++; if( stats[i]->amulet ) stats[i]->amulet->beatitude++; if( stats[i]->ring ) stats[i]->ring->beatitude++; if( stats[i]->mask ) stats[i]->mask->beatitude++; if( multiplayer==SERVER && i>0 ) { strcpy((char *)net_packet->data,"BLES"); net_packet->address.host = net_clients[i-1].host; net_packet->address.port = net_clients[i-1].port; net_packet->len = 4; sendPacketSafe(net_sock, -1, net_packet, i-1); } break; } default: break; } messagePlayer(i, language[474]); my->skill[0] = 0; //Dry up fountain. //TODO: messagePlayersInSight() instead. } //Then perform the effect randomly determined when the fountain was created. return; } } } }
void consoleCommand(char *command_str) { node_t *node; Entity *entity; char name[64]; int c; if( !command_str ) return; if( !strncmp(command_str,"/ping",5) ) { if( multiplayer != CLIENT ) { messagePlayer(clientnum,language[1117],0); } else { strcpy((char *)net_packet->data,"PING"); net_packet->data[4] = clientnum; net_packet->address.host = net_server.host; net_packet->address.port = net_server.port; net_packet->len = 5; sendPacketSafe(net_sock, -1, net_packet, 0); pingtime = SDL_GetTicks(); } } else if (!strncmp(command_str, "/fov", 4)) { fov = atoi(&command_str[5]); fov = std::min(std::max<Uint32>(40,fov),100u); } else if (!strncmp(command_str, "/svflags ", 9)) { if( multiplayer==CLIENT ) { messagePlayer(clientnum,language[275]); } else { svFlags = atoi(&command_str[9]); messagePlayer(clientnum,language[276]); if( multiplayer==SERVER ) { // update client flags strcpy((char *)net_packet->data,"SVFL"); SDLNet_Write32(svFlags,&net_packet->data[4]); net_packet->len = 8; int c; for( c=1; c<MAXPLAYERS; c++ ) { if( client_disconnected[c] ) continue; net_packet->address.host = net_clients[c-1].host; net_packet->address.port = net_clients[c-1].port; sendPacketSafe(net_sock, -1, net_packet, c-1); messagePlayer(c,language[276]); } } } } else if( !strncmp(command_str,"/spawnitem ",11) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } strcpy(name,command_str+11); for( c=0; c<NUMITEMS; c++ ) { if( strstr(items[c].name_identified, name) ) { dropItem(newItem(static_cast<ItemType>(c),EXCELLENT,0,1,rand(),TRUE,&stats[clientnum].inventory),0); break; } } if( c==NUMITEMS ) { messagePlayer(clientnum,language[278],name); } } else if( !strncmp(command_str,"/spawncursed ",13) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } strcpy(name,command_str+13); for( c=0; c<NUMITEMS; c++ ) { if( strstr(items[c].name_identified, name) ) { dropItem(newItem(static_cast<ItemType>(c),WORN,-2,1,rand(),FALSE,&stats[clientnum].inventory),0); break; } } if( c==NUMITEMS ) { messagePlayer(clientnum,language[278],name); } } else if( !strncmp(command_str,"/kick ",6) ) { strcpy(name,command_str+6); if( multiplayer==SERVER ) { for( c=1; c<MAXPLAYERS; c++ ) { if( !client_disconnected[c] && !strncmp(name,stats[c].name,128) ) { client_disconnected[c] = TRUE; strcpy((char *)net_packet->data,"KICK"); net_packet->address.host = net_clients[c-1].host; net_packet->address.port = net_clients[c-1].port; net_packet->len = 4; sendPacketSafe(net_sock, -1, net_packet, c-1); int i; for( i=0; i<MAXPLAYERS; i++ ) { messagePlayer(i,language[279],c,stats[c].name); } break; } } if( c==MAXPLAYERS ) { messagePlayer(clientnum,language[280]); } } else if( multiplayer==CLIENT ) { messagePlayer(clientnum,language[281]); } else { messagePlayer(clientnum,language[282]); } } else if( !strncmp(command_str,"/spawnbook ",11) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } strcpy(name,command_str+11); dropItem(newItem(READABLE_BOOK,EXCELLENT,0,1,getBook(name),TRUE,&stats[clientnum].inventory),0); } else if( !strncmp(command_str,"/savemap ",9) ) { if( command_str[9]!=0 ) { saveMap(command_str+9); messagePlayer(clientnum,language[283],command_str+9); } } else if( !strncmp(command_str,"/nextlevel",10) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } if( multiplayer==CLIENT ) { messagePlayer(clientnum,language[284]); } else { messagePlayer(clientnum,language[285]); loadnextlevel=TRUE; } } else if( !strncmp(command_str,"/pos",4) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } messagePlayer(clientnum,language[286],(int)camera.x,(int)camera.y,(int)camera.z,camera.ang,camera.vang); } else if( !strncmp(command_str,"/pathmap",4) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } if( players[clientnum] ) { int x = std::min<int>(std::max(0.0,floor(players[clientnum]->x/16)),map.width-1); int y = std::min<int>(std::max(0.0,floor(players[clientnum]->y/16)),map.height-1); messagePlayer(clientnum,"pathMapGrounded value: %d",pathMapGrounded[y+x*map.height]); messagePlayer(clientnum,"pathMapFlying value: %d",pathMapFlying[y+x*map.height]); } } else if( !strncmp(command_str,"/exit",5) ) { mainloop=0; } else if( !strncmp(command_str,"/showfps",8) ) { showfps=(showfps==FALSE); } else if( !strncmp(command_str,"/noclip",7) ) { if( multiplayer!=SINGLE ) { messagePlayer(clientnum,language[287]); } else { noclip=(noclip==FALSE); if( noclip ) messagePlayer(clientnum,language[288]); else messagePlayer(clientnum,language[289]); } } else if( !strncmp(command_str,"/god",4) ) { if( multiplayer!=SINGLE ) { messagePlayer(clientnum,language[290]); } else { godmode=(godmode==FALSE); if( godmode ) messagePlayer(clientnum,language[291]); else messagePlayer(clientnum,language[292]); } } else if( !strncmp(command_str,"/buddha",7) ) { if( multiplayer!=SINGLE ) { messagePlayer(clientnum,language[293]); } else { buddhamode=(buddhamode==FALSE); if( buddhamode ) messagePlayer(clientnum,language[294]); else messagePlayer(clientnum,language[295]); } } else if( !strncmp(command_str,"/friendly",9) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } if( multiplayer==CLIENT ) { messagePlayer(clientnum,language[284]); return; } everybodyfriendly=(everybodyfriendly==FALSE); if( everybodyfriendly ) messagePlayer(clientnum,language[296]); else messagePlayer(clientnum,language[297]); } else if( !strncmp(command_str,"/dowse",6) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } for( node=map.entities->first; node!=NULL; node=node->next ) { entity = (Entity *)node->element; if( entity->behavior == &actLadder ) messagePlayer(clientnum,language[298],(int)(entity->x/16),(int)(entity->y/16)); } } else if( !strncmp(command_str,"/thirdperson",12) ) { if( !(svFlags&SV_FLAG_CHEATS) ) { messagePlayer(clientnum,language[277]); return; } if( players[clientnum] != NULL ) { players[clientnum]->skill[3]=(players[clientnum]->skill[3]==0); if( players[clientnum]->skill[3]==1 ) messagePlayer(clientnum,"thirdperson ON"); else messagePlayer(clientnum,"thirdperson OFF"); } } else if( !strncmp(command_str,"/res ",5) ) { xres = atoi(&command_str[5]); for( c=0; c<strlen(command_str); c++ ) { if( command_str[c] == 'x' ) { yres = atoi(&command_str[c+1]); break; } } } else if( !strncmp(command_str,"/rscale",7) ) { rscale = atoi(&command_str[8]); } else if( !strncmp(command_str,"/smoothlighting",15) ) { smoothlighting = (smoothlighting==0); } else if( !strncmp(command_str,"/fullscreen",11) ) { fullscreen = (fullscreen==0); } else if( !strncmp(command_str,"/shaking",8) ) { shaking = (shaking==0); } else if( !strncmp(command_str,"/bobbing",8) ) { bobbing = (bobbing==0); } else if( !strncmp(command_str,"/sfxvolume",10) ) { sfxvolume = atoi(&command_str[11]); } else if( !strncmp(command_str,"/musvolume",10) ) { musvolume = atoi(&command_str[11]); } else if( !strncmp(command_str,"/bind",5) ) { if( strstr(command_str,"IN_FORWARD") ) { impulses[IN_FORWARD] = atoi(&command_str[6]); printlog("Bound IN_FORWARD: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_LEFT") ) { impulses[IN_LEFT] = atoi(&command_str[6]); printlog("Bound IN_LEFT: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_BACK") ) { impulses[IN_BACK] = atoi(&command_str[6]); printlog("Bound IN_BACK: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_RIGHT") ) { impulses[IN_RIGHT] = atoi(&command_str[6]); printlog("Bound IN_RIGHT: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_TURNL") ) { impulses[IN_TURNL] = atoi(&command_str[6]); printlog("Bound IN_TURNL: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_TURNR") ) { impulses[IN_TURNR] = atoi(&command_str[6]); printlog("Bound IN_TURNR: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_UP") ) { impulses[IN_UP] = atoi(&command_str[6]); printlog("Bound IN_UP: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_DOWN") ) { impulses[IN_DOWN] = atoi(&command_str[6]); printlog("Bound IN_DOWN: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_CHAT") ) { impulses[IN_CHAT] = atoi(&command_str[6]); printlog("Bound IN_CHAT: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_COMMAND") ) { impulses[IN_COMMAND] = atoi(&command_str[6]); printlog("Bound IN_COMMAND: %d\n",atoi(&command_str[6])); } else if( strstr(command_str,"IN_STATUS") ) { impulses[IN_STATUS] = atoi(&command_str[6]); printlog("Bound IN_STATUS: %d\n",atoi(&command_str[6])); } else if (strstr(command_str, "IN_SPELL_LIST")) { impulses[IN_SPELL_LIST] = atoi(&command_str[6]); printlog( "Bound IN_SPELL_LIST: %d\n", atoi(&command_str[6])); } else if (strstr(command_str, "IN_CAST_SPELL")) { impulses[IN_CAST_SPELL] = atoi(&command_str[6]); printlog( "Bound IN_CAST_SPELL: %d\n", atoi(&command_str[6])); } else if (strstr(command_str, "IN_DEFEND")) { impulses[IN_DEFEND] = atoi(&command_str[6]); printlog( "Bound IN_DEFEND: %d\n", atoi(&command_str[6])); } else if (strstr(command_str, "IN_ATTACK")) { impulses[IN_ATTACK] = atoi(&command_str[6]); printlog( "Bound IN_ATTACK: %d\n", atoi(&command_str[6])); } else if (strstr(command_str, "IN_USE")) { impulses[IN_USE] = atoi(&command_str[6]); printlog( "Bound IN_USE: %d\n", atoi(&command_str[6])); } else { messagePlayer(clientnum,"Invalid binding."); } } else if( !strncmp(command_str,"/mousespeed",11) ) { mousespeed = atoi(&command_str[12]); } else if( !strncmp(command_str,"/reversemouse",13) ) { reversemouse = (reversemouse==0); } else if( !strncmp(command_str,"/smoothmouse",12) ) { smoothmouse = (smoothmouse==FALSE); } else if( !strncmp(command_str,"/mana", 4) ) { if( multiplayer == SINGLE ) { stats[clientnum].MP = stats[clientnum].MAXMP; } else { messagePlayer(clientnum,language[299]); } } else if( !strncmp(command_str,"/heal", 4) ) { if( multiplayer == SINGLE ) { stats[clientnum].HP = stats[clientnum].MAXHP; } else { messagePlayer(clientnum,language[299]); } } else if (!strncmp(command_str, "/ip ", 4)) { if( command_str[4]!=0 ) { strcpy(last_ip, command_str + 4); last_ip[strlen(last_ip)-1]=0; } } else if (!strncmp(command_str, "/port ", 6)) { if (command_str[6] != 0) { strcpy(last_port, command_str + 6); last_port[strlen(last_port)-1]=0; } } else if (!strncmp(command_str, "/noblood", 8)) { spawn_blood = (spawn_blood==FALSE); } else if(!strncmp(command_str, "/colorblind", 11)) { colorblind = (colorblind==FALSE); } else if (!strncmp(command_str, "/gamma", 6)) { std::stringstream ss; ss << command_str + 7; ss >> vidgamma; }
void actFountain(Entity* my) { Entity* entity; //messagePlayer(0, "actFountain()"); //TODO: Temporary mechanism testing code. /* if( multiplayer != CLIENT ) { if (my->skill[28]) { //All it does is change its sprite to sink if it's powered. if (my->skill[28] == 1) { my->sprite = 163; } else { my->sprite = 164; } } }*/ //****************END TEST CODE*************** //TODO: Sounds. // spray water if ( my->skill[0] > 0 ) { #define FOUNTAIN_AMBIENCE my->skill[7] FOUNTAIN_AMBIENCE--; if ( FOUNTAIN_AMBIENCE <= 0 ) { FOUNTAIN_AMBIENCE = TICKS_PER_SECOND * 6; playSoundEntityLocal(my, 135, 32 ); } entity = spawnGib(my); entity->flags[INVISIBLE] = false; entity->y -= 2; entity->z -= 8; entity->flags[SPRITE] = false; entity->flags[NOUPDATE] = true; entity->flags[UPDATENEEDED] = false; entity->skill[4] = 7; entity->sprite = 4; entity->yaw = (rand() % 360) * PI / 180.0; entity->pitch = (rand() % 360) * PI / 180.0; entity->roll = (rand() % 360) * PI / 180.0; entity->vel_x = 0; entity->vel_y = 0; entity->vel_z = .25; entity->fskill[3] = 0.03; } // the rest of the function is server-side. if ( multiplayer == CLIENT ) { return; } //Using the fountain (TODO: Monsters using it?). int i; for (i = 0; i < MAXPLAYERS; ++i) { if ( (i == 0 && selectedEntity == my) || (client_selected[i] == my) ) { if (inrange[i]) //Act on it only if the player (or monster, if/when this is changed to support monster interaction?) is in range. { //First check that it's not depleted. if (my->skill[0] == 0) { //Depleted messagePlayer(i, language[467]); } else { if (players[i]->entity->flags[BURNING]) { messagePlayer(i, language[468]); players[i]->entity->flags[BURNING] = false; serverUpdateEntityFlag(players[i]->entity, BURNING); steamAchievementClient(i, "BARONY_ACH_HOT_SHOWER"); } switch (my->skill[1]) { case 0: { playSoundEntity(players[i]->entity, 52, 64); //Spawn succubus. Uint32 color = SDL_MapRGB(mainsurface->format, 255, 128, 0); Entity* spawnedMonster = nullptr; if ( !strncmp(map.name, "Underworld", 10) ) { Monster creature = SUCCUBUS; if ( rand() % 2 ) { creature = INCUBUS; } for ( int c = 0; spawnedMonster == nullptr && c < 5; ++c ) { switch ( c ) { case 0: spawnedMonster = summonMonster(creature, my->x, my->y); break; case 1: spawnedMonster = summonMonster(creature, my->x + 16, my->y); break; case 2: spawnedMonster = summonMonster(creature, my->x - 16, my->y); break; case 3: spawnedMonster = summonMonster(creature, my->x, my->y + 16); break; case 4: spawnedMonster = summonMonster(creature, my->x, my->y - 16); break; } } if ( spawnedMonster ) { if ( creature == INCUBUS ) { messagePlayerColor(i, color, language[2519]); Stat* tmpStats = spawnedMonster->getStats(); if ( tmpStats ) { strcpy(tmpStats->name, "lesser incubus"); } } else { messagePlayerColor(i, color, language[469]); } } } else if ( currentlevel < 10 ) { messagePlayerColor(i, color, language[469]); spawnedMonster = summonMonster(SUCCUBUS, my->x, my->y); } else if ( currentlevel < 20 ) { if ( rand() % 2 ) { spawnedMonster = summonMonster(INCUBUS, my->x, my->y); Stat* tmpStats = spawnedMonster->getStats(); if ( tmpStats ) { strcpy(tmpStats->name, "lesser incubus"); } messagePlayerColor(i, color, language[2519]); } else { messagePlayerColor(i, color, language[469]); spawnedMonster = summonMonster(SUCCUBUS, my->x, my->y); } } else { messagePlayerColor(i, color, language[2519]); spawnedMonster = summonMonster(INCUBUS, my->x, my->y); } break; } case 1: messagePlayer(i, language[470]); messagePlayer(i, language[471]); playSoundEntity(players[i]->entity, 52, 64); stats[i]->HUNGER += 100; players[i]->entity->modHP(5); break; case 2: { //Potion effect. Potion effect is stored in my->skill[3], randomly chosen when the fountain is created. messagePlayer(i, language[470]); Item* item = newItem(static_cast<ItemType>(POTION_WATER + my->skill[3]), static_cast<Status>(4), 0, 1, 0, false, NULL); useItem(item, i); // Long live the mystical fountain of TODO. break; } case 3: { // bless all equipment playSoundEntity(players[i]->entity, 52, 64); Uint32 textcolor = SDL_MapRGB(mainsurface->format, 0, 255, 255); messagePlayerColor(i, textcolor, language[471]); messagePlayer(i, language[473]); if ( stats[i]->helmet ) { stats[i]->helmet->beatitude++; } if ( stats[i]->breastplate ) { stats[i]->breastplate->beatitude++; } if ( stats[i]->gloves ) { stats[i]->gloves->beatitude++; } if ( stats[i]->shoes ) { stats[i]->shoes->beatitude++; } if ( stats[i]->shield ) { stats[i]->shield->beatitude++; } if ( stats[i]->weapon ) { stats[i]->weapon->beatitude++; } if ( stats[i]->cloak ) { stats[i]->cloak->beatitude++; } if ( stats[i]->amulet ) { stats[i]->amulet->beatitude++; } if ( stats[i]->ring ) { stats[i]->ring->beatitude++; } if ( stats[i]->mask ) { stats[i]->mask->beatitude++; } if ( multiplayer == SERVER && i > 0 ) { strcpy((char*)net_packet->data, "BLES"); net_packet->address.host = net_clients[i - 1].host; net_packet->address.port = net_clients[i - 1].port; net_packet->len = 4; sendPacketSafe(net_sock, -1, net_packet, i - 1); } break; } case 4: { // bless one piece of equipment playSoundEntity(players[i]->entity, 52, 64); Uint32 textcolor = SDL_MapRGB(mainsurface->format, 0, 255, 255); messagePlayerColor(i, textcolor, language[471]); //Choose only one piece of equipment to bless. //First, Figure out what equipment is available. std::vector<std::pair<Item*, Uint32>> items; if ( stats[i]->helmet ) { items.push_back(std::pair<Item*,int>(stats[i]->helmet, 0)); } if ( stats[i]->breastplate ) { items.push_back(std::pair<Item*,int>(stats[i]->breastplate, 1)); } if ( stats[i]->gloves ) { items.push_back(std::pair<Item*,int>(stats[i]->gloves, 2)); } if ( stats[i]->shoes ) { items.push_back(std::pair<Item*,int>(stats[i]->shoes, 3)); } if ( stats[i]->shield ) { items.push_back(std::pair<Item*,int>(stats[i]->shield, 4)); } if ( stats[i]->weapon ) { items.push_back(std::pair<Item*,int>(stats[i]->weapon, 5)); } if ( stats[i]->cloak ) { items.push_back(std::pair<Item*,int>(stats[i]->cloak, 6)); } if ( stats[i]->amulet ) { items.push_back(std::pair<Item*,int>(stats[i]->amulet, 7)); } if ( stats[i]->ring ) { items.push_back(std::pair<Item*,int>(stats[i]->ring, 8)); } if ( stats[i]->mask ) { items.push_back(std::pair<Item*,int>(stats[i]->mask, 9)); } if ( items.size() ) { messagePlayer(i, language[2592]); //"The fountain blesses a piece of equipment" //Randomly choose a piece of equipment. std::pair<Item*, Uint32> chosen = items[rand()%items.size()]; chosen.first->beatitude++; if ( multiplayer == SERVER && i > 0 ) { strcpy((char*)net_packet->data, "BLE1"); SDLNet_Write32(chosen.second, &net_packet->data[4]); net_packet->address.host = net_clients[i - 1].host; net_packet->address.port = net_clients[i - 1].port; net_packet->len = 8; sendPacketSafe(net_sock, -1, net_packet, i - 1); } } //Does nothing if no valid items. break; } default: break; } messagePlayer(i, language[474]); my->skill[0] = 0; //Dry up fountain. serverUpdateEntitySkill(my, my->skill[0]); //TODO: messagePlayersInSight() instead. } //Then perform the effect randomly determined when the fountain was created. return; } } } }
int boulderCheckAgainstEntity(Entity *my, Entity *entity) { if (!my || !entity) return 0; if( entity->behavior == &actPlayer || entity->behavior == &actMonster ) { if( entityInsideEntity( my, entity ) ) { Stat *stats = entity->getStats(); if( stats ) { if( entity->behavior==&actPlayer ) { Uint32 color = SDL_MapRGB(mainsurface->format,255,0,0); messagePlayerColor(entity->skill[2],color,language[455]); if( entity->skill[2] == clientnum ) { camera_shakex += .1; camera_shakey += 10; } else { strcpy((char *)net_packet->data,"SHAK"); net_packet->data[4]=10; // turns into .1 net_packet->data[5]=10; net_packet->address.host = net_clients[entity->skill[2]-1].host; net_packet->address.port = net_clients[entity->skill[2]-1].port; net_packet->len = 6; sendPacketSafe(net_sock, -1, net_packet, entity->skill[2]-1); } } playSoundEntity(my,181,128); playSoundEntity(entity,28,64); spawnGib(entity); entity->modHP(-80); entity->setObituary(language[1505]); if( entity->behavior==&actPlayer ) if( stats->HP<=0 ) steamAchievementClient(entity->skill[2],"BARONY_ACH_THROW_ME_THE_WHIP"); if( stats->HP > 0 ) { // spawn several rock items int i = 8+rand()%4; int c; for( c=0; c<i; c++ ) { Entity *entity = newEntity(-1,1,map.entities); entity->flags[INVISIBLE]=TRUE; entity->flags[UPDATENEEDED]=TRUE; entity->x = my->x - 4 + rand()%8; entity->y = my->y - 4 + rand()%8; entity->z = -6+rand()%12; entity->sizex = 4; entity->sizey = 4; entity->yaw = rand()%360 * PI/180; entity->vel_x = (rand()%20-10)/10.0; entity->vel_y = (rand()%20-10)/10.0; entity->vel_z = -.25 - (rand()%5)/10.0; entity->flags[PASSABLE] = TRUE; entity->behavior = &actItem; entity->flags[USERFLAG1] = TRUE; // no collision: helps performance entity->skill[10] = GEM_ROCK; // type entity->skill[11] = WORN; // status entity->skill[12] = 0; // beatitude entity->skill[13] = 1; // count entity->skill[14] = 0; // appearance entity->skill[15] = FALSE; // identified } double ox = my->x; double oy = my->y; // destroy the boulder playSoundEntity(my,67,128); list_RemoveNode(my->mynode); // on sokoban, destroying boulders spawns scorpions if( !strcmp(map.name,"Sokoban") ) { Entity *monster = summonMonster(SCORPION,ox,oy); if( monster ) { int c; for( c=0; c<MAXPLAYERS; c++ ) { Uint32 color = SDL_MapRGB(mainsurface->format,255,128,0); messagePlayerColor(c,color,language[406]); } } } return 1; } } } } else if( entity->behavior == &actGate || entity->behavior == &actBoulder || entity->behavior==&actChest || entity->behavior==&actHeadstone || entity->behavior==&actFountain || entity->behavior==&actSink ) { if( !entity->flags[PASSABLE] ) { if( entityInsideEntity( my, entity ) ) { // stop the boulder BOULDER_STOPPED=1; BOULDER_ROLLING=0; playSoundEntity(my,181,128); if( my->flags[PASSABLE] ) { my->flags[PASSABLE] = FALSE; if( multiplayer==SERVER ) serverUpdateEntityFlag(my,PASSABLE); } } } } else if( entity->behavior == &actDoor ) { if( entityInsideEntity( my, entity ) ) { playSoundEntity(entity,28,64); entity->skill[4] = 0; if( !entity->skill[0] ) entity->skill[6] = (my->x > entity->x); else entity->skill[6] = (my->y < entity->y); playSoundEntity(my,181,128); } } return 0; }
void castSpellInit(Uint32 caster_uid, spell_t *spell){ Entity *caster = uidToEntity(caster_uid); node_t *node = NULL; if (!caster || !spell) { //Need a spell and caster to cast a spell. return; } if (!spell->elements.first) { return; } if (hudweapon) { if (hudweapon->skill[0] != 0) { //HUDWEAPON_CHOP. return; //Can't cast spells while attacking. } } if (cast_animation.active) { //Already casting spell. return; } int player = -1; int i = 0; for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { player = i; //Set the player. } } if (player > -1) { if( stats[player].defending ) { messagePlayer(player,language[407]); return; } if (spell_isChanneled(spell)) { if (channeledSpells[clientnum], spell) { for (node = channeledSpells[player].first; node; node = node->next) { spell_t *spell_search = (spell_t*)node->element; if (spell_search->ID == spell->ID) { //list_RemoveNode(node); //node = NULL; spell_search->sustain = FALSE; //if (spell->magic_effects) // list_RemoveNode(spell->magic_effects); messagePlayer(player, language[408], spell->name); if (multiplayer == CLIENT) { list_RemoveNode(node); strcpy( (char *)net_packet->data, "UNCH"); net_packet->data[4] = clientnum; SDLNet_Write32(spell->ID, &net_packet->data[5]); net_packet->address.host = net_server.host; net_packet->address.port = net_server.port; net_packet->len = 9; sendPacketSafe(net_sock, -1, net_packet, 0); } return; } } } } } int magiccost = 0; //Entity *entity = NULL; //node_t *node = spell->elements->first; stat_t *stat = caster->getStats(); if( !stat ) return; if (stat->EFFECTS[EFF_PARALYZED]) { return; } magiccost = getCostOfSpell(spell); if (magiccost > stat->MP) { if (player >= 0) messagePlayer(player, language[375]); //TODO: Allow overexpending at the cost of extreme danger? (maybe an immensely powerful tree of magic actually likes this -- using your life-force to power spells instead of mana) return; } if (magiccost < 0) { if (player >= 0) messagePlayer(player, "Error: Invalid spell. Mana cost is negative?"); return; } //Hand the torch off to the spell animator. And stuff. Stuff. I mean spell animation handler thingymabobber. fireOffSpellAnimation(&cast_animation, caster->uid, spell); //castSpell(caster, spell); //For now, do this while the spell animations are worked on. }
Entity* castSpell(Uint32 caster_uid, spell_t *spell, bool using_magicstaff, bool trap) { Entity *caster = uidToEntity(caster_uid); if (!caster || !spell) { //Need a spell and caster to cast a spell. return NULL; } Entity *result = NULL; //If the spell spawns an entity (like a magic light ball or a magic missile), it gets stored here and returned. #define spellcasting std::min(std::max(0,stat->PROFICIENCIES[PRO_SPELLCASTING]+statGetINT(stat)),100) //Shortcut! if (clientnum != 0 && multiplayer == CLIENT) { strcpy( (char *)net_packet->data, "SPEL" ); net_packet->data[4] = clientnum; SDLNet_Write32(spell->ID, &net_packet->data[5]); net_packet->address.host = net_server.host; net_packet->address.port = net_server.port; net_packet->len = 9; sendPacketSafe(net_sock, -1, net_packet, 0); return NULL; } if (!spell->elements.first) { return NULL; } //node_t *node = spell->types->first; #define PROPULSION_MISSILE 1 int i = 0; int chance = 0; int propulsion = 0; int traveltime = 0; int magiccost = 0; int extramagic = 0; //Extra magic drawn in from the caster being a newbie. int extramagic_to_use = 0; //Instead of doing element->mana (which causes bugs), this is an extra factor in the mana equations. Pumps extra mana into elements from extramagic. Entity *entity = NULL; spell_t *channeled_spell=NULL; //Pointer to the spell if it's a channeled spell. For the purpose of giving it its node in the channeled spell list. node_t *node = spell->elements.first; stat_t *stat = caster->getStats(); int player = -1; for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { player = i; //Set the player. } } bool newbie = FALSE; if( !using_magicstaff && !trap) { if (stat->PROFICIENCIES[PRO_SPELLCASTING] < SPELLCASTING_BEGINNER) { newbie = TRUE; //The caster has lower spellcasting skill. Cue happy fun times. } /*magiccost = getCostOfSpell(spell); if (magiccost < 0) { if (player >= 0) messagePlayer(player, "Error: Invalid spell. Mana cost is negative?"); return NULL; }*/ if (multiplayer == SINGLE) { magiccost = cast_animation.mana_left; caster->drainMP(magiccost); } else { magiccost = getCostOfSpell(spell); caster->drainMP(magiccost); } } if (newbie) { //So This wizard is a newbie. //First, drain some extra mana maybe. int chance = rand()%10; if (chance >= spellcasting/10) { //At skill 20, there's an 80% chance you'll use extra mana. At 70, there's a 30% chance. extramagic = rand()%(300/(spellcasting+1)); //Use up extra mana. More mana used the lower your spellcasting skill. extramagic = std::min(extramagic, stat->MP / 10); //To make sure it doesn't draw, say, 5000 mana. Cause dammit, if you roll a 1 here...you're doomed. caster->drainMP(extramagic); } //Now, there's a chance they'll fumble the spell. chance = rand()%10; if (chance >= spellcasting/10) { if (rand()%3 == 1) { //Fizzle the spell. //TODO: Cool effects. playSoundEntity(caster,163,128); if (player >= 0) messagePlayer(player, language[409]); return NULL; } } } //Check if the bugger is levitating. bool levitating = FALSE; if (!trap) { if (stat->EFFECTS[EFF_LEVITATING] == TRUE ) levitating=TRUE; if (stat->ring != NULL ) if (stat->ring->type == RING_LEVITATION ) levitating = TRUE; if (stat->shoes != NULL) if (stat->shoes->type == STEEL_BOOTS_LEVITATION ) levitating = TRUE; } //Water walking boots bool waterwalkingboots = FALSE; if (!trap) { if (stat->shoes != NULL) if (stat->shoes->type == IRON_BOOTS_WATERWALKING ) waterwalkingboots = TRUE; } node_t *node2; //For traversing the map looking for...liquids? //Check if swimming. if (!waterwalkingboots && !levitating && !trap && player>=0) { bool swimming=FALSE; if( players[player] ) { int x = std::min<int>(std::max(0.0,floor(caster->x/16)),map.width-1); int y = std::min<int>(std::max(0.0,floor(caster->y/16)),map.height-1); if( animatedtiles[map.tiles[y*MAPLAYERS+x*MAPLAYERS*map.height]] ) swimming=TRUE; } if( swimming ) { //Can't cast spells while swimming if not levitating or water walking. if (player >= 0) messagePlayer(player, language[410]); return NULL; } } //Right. First, grab the root element, which is what determines the delivery system. //spellElement_t *element = (spellElement_t *)spell->elements->first->element; spellElement_t *element = (spellElement_t *)node->element; if (element) { extramagic_to_use = 0; /*if (magiccost > stat->MP) { if (player >= 0) messagePlayer(player, "Insufficient mana!"); //TODO: Allow overexpending at the cost of extreme danger? (maybe an immensely powerful tree of magic actually likes this -- using your life-force to power spells instead of mana) return NULL; }*/ if (extramagic > 0) { //Extra magic. Pump it in here? chance = rand()%5; if (chance == 1) { //Use some of that extra magic in this element. int amount = rand()%extramagic; extramagic -= amount; extramagic_to_use += amount; } } if (!strcmp(element->name, spellElement_missile.name)) { //Set the propulsion to missile. propulsion = PROPULSION_MISSILE; traveltime = element->duration; if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) traveltime -= rand()%(1000/(spellcasting+1)); if (traveltime < 30) traveltime = 30; //Range checking. } traveltime += (((element->mana + extramagic_to_use) - element->base_mana) / element->overload_multiplier) * element->duration; } else if (!strcmp(element->name, spellElement_light.name)) { entity = newEntity(175, 1, map.entities); // black magic ball entity->parent = caster->uid; entity->x = caster->x; entity->y = caster->y; entity->z = -5.5 + ((-6.5f + -4.5f) / 2) * sin(0); entity->skill[7] = -5.5; //Base z. entity->sizex = 1; entity->sizey = 1; entity->yaw = caster->yaw; entity->flags[UPDATENEEDED]=TRUE; entity->flags[PASSABLE]=TRUE; entity->flags[BRIGHT]=TRUE; entity->behavior=&actMagiclightBall; entity->skill[4] = entity->x; //Store what x it started shooting out from the player at. entity->skill[5] = entity->y; //Store what y it started shooting out from the player at. entity->skill[12] = (element->duration * (((element->mana + extramagic_to_use) / element->base_mana) * element->overload_multiplier)); //How long this thing lives. node_t *spellnode = list_AddNodeLast(&entity->children); spellnode->element = copySpell(spell); //We need to save the spell since this is a channeled spell. channeled_spell = (spell_t*)(spellnode->element); spellnode->size = sizeof(spell_t); ((spell_t *)spellnode->element)->caster = caster->uid; if( using_magicstaff ) ((spell_t *)spellnode->element)->magicstaff = TRUE; spellnode->deconstructor = &spellDeconstructor; if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) { // lifespan of the lightball entity->skill[12] -= rand()%(2000/(spellcasting+1)); if (entity->skill[12] < 180) entity->skill[12] = 180; //Range checking. } } if (using_magicstaff || trap) { entity->skill[12] = MAGICSTAFF_LIGHT_DURATION; //TODO: Grab the duration from the magicstaff or trap? ((spell_t *)spellnode->element)->sustain = FALSE; } else { entity->skill[12] /= getCostOfSpell((spell_t *)spellnode->element); } ((spell_t *)spellnode->element)->channel_duration = entity->skill[12]; //Tell the spell how long it's supposed to last so that it knows what to reset its timer to. result = entity; playSoundEntity(entity, 165, 128 ); } else if (!strcmp(element->name, spellElement_invisible.name)) { int duration = element->duration; duration += (((element->mana + extramagic_to_use) - element->base_mana) / element->overload_multiplier) * element->duration; node_t *spellnode = list_AddNodeLast(&caster->getStats()->magic_effects); spellnode->element = copySpell(spell); //We need to save the spell since this is a channeled spell. channeled_spell = (spell_t*)(spellnode->element); channeled_spell->magic_effects_node = spellnode; spellnode->size = sizeof(spell_t); ((spell_t *)spellnode->element)->caster = caster->uid; spellnode->deconstructor = &spellDeconstructor; if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) duration -= rand()%(1000/(spellcasting+1)); if (duration < 180) duration = 180; //Range checking. } duration /= getCostOfSpell((spell_t *)spellnode->element); channeled_spell->channel_duration = duration; //Tell the spell how long it's supposed to last so that it knows what to reset its timer to. stat->EFFECTS[EFF_INVISIBLE] = TRUE; stat->EFFECTS_TIMERS[EFF_INVISIBLE] = duration; for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { serverUpdateEffects(i); } } playSoundEntity(caster, 166, 128 ); spawnMagicEffectParticles(caster->x,caster->y,caster->z,174); } else if (!strcmp(element->name, spellElement_levitation.name)) { int duration = element->duration; duration += (((element->mana + extramagic_to_use) - element->base_mana) / element->overload_multiplier) * element->duration; node_t *spellnode = list_AddNodeLast(&caster->getStats()->magic_effects); spellnode->element = copySpell(spell); //We need to save the spell since this is a channeled spell. channeled_spell = (spell_t*)(spellnode->element); channeled_spell->magic_effects_node = spellnode; spellnode->size = sizeof(spell_t); ((spell_t *)spellnode->element)->caster = caster->uid; spellnode->deconstructor = &spellDeconstructor; if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) duration -= rand()%(1000/(spellcasting+1)); if (duration < 180) duration = 180; //Range checking. } duration /= getCostOfSpell((spell_t *)spellnode->element); channeled_spell->channel_duration = duration; //Tell the spell how long it's supposed to last so that it knows what to reset its timer to. stat->EFFECTS[EFF_LEVITATING] = TRUE; stat->EFFECTS_TIMERS[EFF_LEVITATING] = duration; for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { serverUpdateEffects(i); } } playSoundEntity(caster, 178, 128 ); spawnMagicEffectParticles(caster->x,caster->y,caster->z,170); } else if (!strcmp(element->name, spellElement_teleportation.name)) { caster->teleportRandom(); } else if (!strcmp(element->name, spellElement_identify.name)) { for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { spawnMagicEffectParticles(caster->x,caster->y,caster->z,171); if (i != 0) { //Tell the client to identify an item. strcpy((char *)net_packet->data,"IDEN"); net_packet->address.host = net_clients[i - 1].host; net_packet->address.port = net_clients[i - 1].port; net_packet->len = 4; sendPacketSafe(net_sock, -1, net_packet, i-1); } else { //Identify an item. shootmode = FALSE; gui_mode = GUI_MODE_INVENTORY; //Reset the GUI to the inventory. identifygui_active = TRUE; identifygui_appraising = FALSE; //identifygui_mode = TRUE; } } } playSoundEntity(caster, 167, 128 ); } else if (!strcmp(element->name, spellElement_removecurse.name)) { for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { spawnMagicEffectParticles(caster->x,caster->y,caster->z,169); if (i != 0) { //Tell the client to uncurse an item. strcpy((char *)net_packet->data,"RCUR"); net_packet->address.host = net_clients[i - 1].host; net_packet->address.port = net_clients[i - 1].port; net_packet->len = 4; sendPacketSafe(net_sock, -1, net_packet, i-1); } else { //Uncurse an item shootmode = FALSE; gui_mode = GUI_MODE_INVENTORY; //Reset the GUI to the inventory. removecursegui_active = TRUE; } } } playSoundEntity(caster, 167, 128 ); } else if (!strcmp(element->name, spellElement_magicmapping.name)) { for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { spawnMagicEffectParticles(caster->x,caster->y,caster->z,171); spell_magicMap(i); } } playSoundEntity(caster, 167, 128 ); } else if (!strcmp(element->name, spellElement_heal.name)) { //TODO: Make it work for NPCs. for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { int amount = element->damage * (((element->mana + extramagic_to_use) / element->base_mana) * element->overload_multiplier); //Amount to heal. if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) amount -= rand()%(1000/(spellcasting+1)); if (amount < 8) amount = 8; //Range checking. } spell_changeHealth(players[i], amount); playSoundEntity(caster, 168, 128); for(node = map.entities->first; node->next; node = node->next) { entity = (Entity *)(node->element); if ( !entity || entity==caster ) continue; if( entity->behavior!=&actPlayer && entity->behavior!=&actMonster ) continue; if (entityDist(entity, caster) <= HEAL_RADIUS && entity->checkFriend(caster)) { spell_changeHealth(entity, amount); playSoundEntity(entity, 168, 128); spawnMagicEffectParticles(entity->x,entity->y,entity->z,169); } } break; } } playSoundEntity(caster, 168, 128); spawnMagicEffectParticles(caster->x,caster->y,caster->z,169); } else if (!strcmp(element->name, spellElement_cure_ailment.name)) { //TODO: Generalize it for NPCs too? for (i = 0; i < numplayers; ++i) { if (caster == players[i]) { Uint32 color = SDL_MapRGB(mainsurface->format,0,255,0); messagePlayerColor(i,color,language[411]); int c = 0; for (c = 0; c < NUMEFFECTS; ++c) { //This does a whole lot more than just cure ailments. stats[i].EFFECTS[c]=FALSE; stats[i].EFFECTS_TIMERS[c]=0; } serverUpdateEffects(player); playSoundEntity(entity, 168, 128); for(node = map.entities->first; node->next; node = node->next) { entity = (Entity *)(node->element); if( !entity || entity==caster ) continue; if( entity->behavior!=&actPlayer && entity->behavior!=&actMonster ) continue; stat_t *target_stat = entity->getStats(); if( target_stat ) { if (entityDist(entity, caster) <= HEAL_RADIUS && entity->checkFriend(caster)) { for (c = 0; c < NUMEFFECTS; ++c) { //This does a whole lot more than just cure ailments. target_stat->EFFECTS[c]=FALSE; target_stat->EFFECTS_TIMERS[c]=0; } if( entity->behavior==&actPlayer ) serverUpdateEffects(entity->skill[2]); if( entity->flags[BURNING] ) { entity->flags[BURNING] = FALSE; serverUpdateEntityFlag(entity,BURNING); } playSoundEntity(entity, 168, 128); spawnMagicEffectParticles(entity->x,entity->y,entity->z,169); } } } break; } } playSoundEntity(caster, 168, 128 ); spawnMagicEffectParticles(caster->x,caster->y,caster->z,169); } if (propulsion == PROPULSION_MISSILE) { entity = newEntity(168, 1, map.entities); // red magic ball entity->parent = caster->uid; entity->x = caster->x; entity->y = caster->y; entity->z = -1; entity->sizex = 1; entity->sizey = 1; entity->yaw = caster->yaw; entity->flags[UPDATENEEDED]=TRUE; entity->flags[PASSABLE]=TRUE; entity->flags[BRIGHT]=TRUE; entity->behavior = &actMagicMissile; double missile_speed = 4 * ((double)element->mana / element->overload_multiplier); //TODO: Factor in base mana cost? entity->vel_x = cos(entity->yaw) * (missile_speed); entity->vel_y = sin(entity->yaw) * (missile_speed); entity->skill[4] = 0; entity->skill[5] = traveltime; node = list_AddNodeFirst(&entity->children); node->element = copySpell(spell); ((spell_t *)node->element)->caster = caster->uid; node->deconstructor = &spellDeconstructor; node->size = sizeof(spell_t); if( !strcmp(spell->name, spell_fireball.name) ) playSoundEntity(entity, 164, 128 ); else if( !strcmp(spell->name, spell_lightning.name) ) playSoundEntity(entity, 171, 128 ); else if( !strcmp(spell->name, spell_cold.name) ) playSoundEntity(entity, 172, 128 ); else playSoundEntity(entity, 169, 128 ); result = entity; } extramagic_to_use = 0; if (extramagic > 0) { //Extra magic. Pump it in here? chance = rand()%5; if (chance == 1) { //Use some of that extra magic in this element. int amount = rand()%extramagic; extramagic -= amount; extramagic_to_use += amount; //TODO: Make the elements here use this? Looks like they won't, currently. Oh well. } } //TODO: Add the status/conditional elements/modifiers (probably best as elements) too. Like onCollision or something. //element = (spellElement_t *)element->elements->first->element; node = element->elements.first; if( node ) { element = (spellElement_t *)node->element; if (!strcmp(element->name, spellElement_force.name)) { //Give the spell force properties. if (propulsion == PROPULSION_MISSILE) { entity->sprite = 173; } if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) element->damage -= rand()%(100/(spellcasting+1)); if (element->damage < 10) element->damage = 10; //Range checking. } } else if (!strcmp(element->name, spellElement_fire.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 168; //entity->skill[4] = entity->x; //Store what x it started shooting out from the player at. //entity->skill[5] = entity->y; //Store what y it started shooting out from the player at. //entity->skill[12] = (100 * stat->PROFICIENCIES[PRO_SPELLCASTING]) + (100 * stat->PROFICIENCIES[PRO_MAGIC]) + (100 * (rand()%10)) + (10 * (rand()%10)) + (rand()%10); //How long this thing lives. //playSoundEntity( entity, 59, 128 ); } if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) element->damage -= rand()%(100/(spellcasting+1)); if (element->damage < 10) element->damage = 10; //Range checking. } } else if (!strcmp(element->name, spellElement_lightning.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 170; } if (newbie) { //This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell. chance = rand()%10; if (chance >= spellcasting/10) element->damage -= rand()%(100/(spellcasting+1)); if (element->damage < 10) element->damage = 10; //Range checking. } } else if (!strcmp(element->name, spellElement_confuse.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 173; } } else if (!strcmp(element->name, spellElement_cold.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 172; } } else if (!strcmp(element->name, spellElement_dig.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 171; } } else if (!strcmp(element->name, spellElement_locking.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 171; } } else if (!strcmp(element->name, spellElement_opening.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 171; } } else if (!strcmp(element->name, spellElement_slow.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 171; } } else if (!strcmp(element->name, spellElement_sleep.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 172; } } else if (!strcmp(spell->name, spell_magicmissile.name)) { if (propulsion == PROPULSION_MISSILE) { entity->sprite = 173; } } } } //Random chance to level up spellcasting skill. if(rand()%4==0) { caster->increaseSkill(PRO_SPELLCASTING); } if(rand()%5==0) { caster->increaseSkill(PRO_MAGIC); // otherwise you will basically never be able to learn all the spells in the game... } if (spell_isChanneled(spell) && !using_magicstaff) { //TODO: What about magic traps and channeled spells? if (!channeled_spell) { printlog( "What. Spell is channeled but no channeled_spell pointer? What sorcery is this?\n"); } else { int target_client = 0; for (i = 0; i < numplayers; ++i) { if (players[i] == caster) { target_client = i; } } //printlog( "Client is: %d\n", target_client); if (multiplayer == SERVER && target_client != 0) { strcpy( (char *)net_packet->data, "CHAN" ); net_packet->data[4] = clientnum; SDLNet_Write32(spell->ID, &net_packet->data[5]); net_packet->address.host = net_clients[target_client - 1].host; net_packet->address.port = net_clients[target_client - 1].port; net_packet->len = 9; sendPacketSafe(net_sock, -1, net_packet, target_client-1); } //Add this spell to the list of channeled spells. node = list_AddNodeLast(&channeledSpells[target_client]); node->element = channeled_spell; node->size = sizeof(spell_t); node->deconstructor = &emptyDeconstructor; channeled_spell->sustain_node = node; } } return result; }
void actWinningPortal(Entity *my) { int playercount=0; double dist; int i, c; if( multiplayer!=CLIENT ) { if( my->flags[INVISIBLE] ) { node_t *node; for( node=map.entities->first; node!=NULL; node=node->next ) { Entity *entity = (Entity *)node->element; if( entity->behavior==&actMonster ) { Stat *stats = entity->getStats(); if( stats ) { if( stats->type == LICH || stats->type == DEVIL ) { return; } } } } my->flags[INVISIBLE] = FALSE; } } else { if( my->flags[INVISIBLE] ) return; } if( !PORTAL_INIT ) { PORTAL_INIT=1; my->light = lightSphereShadow(my->x/16,my->y/16,3,255); } PORTAL_AMBIENCE--; if( PORTAL_AMBIENCE<=0 ) { PORTAL_AMBIENCE = TICKS_PER_SECOND*2; playSoundEntityLocal( my, 154, 128 ); } my->yaw += 0.01; // rotate slowly on my axis my->sprite = 278+(my->ticks/20)%4; // animate if( multiplayer==CLIENT ) return; // step through portal for(i=0;i<MAXPLAYERS;i++) { if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) { if(inrange[i]) { for( c=0; c<MAXPLAYERS; c++ ) { if( client_disconnected[c] || players[c] == NULL ) continue; else playercount++; dist = sqrt( pow(my->x-players[c]->x,2) + pow(my->y-players[c]->y,2) ); if( dist > TOUCHRANGE ) { messagePlayer(i,language[509]); return; } } victory = PORTAL_VICTORYTYPE; if( multiplayer==SERVER ) { for( c=0; c<MAXPLAYERS; c++ ) { if( client_disconnected[c]==TRUE ) continue; strcpy((char *)net_packet->data,"WING"); net_packet->data[4] = victory; net_packet->address.host = net_clients[c-1].host; net_packet->address.port = net_clients[c-1].port; net_packet->len = 8; sendPacketSafe(net_sock, -1, net_packet, c-1); } } subwindow=0; introstage=5; // prepares win game sequence fadeout=TRUE; if( !intro ) pauseGame(2,FALSE); return; } } } }
void startTradingServer(Entity* entity, int player) { if (!entity) { return; } if ( multiplayer == CLIENT ) { return; } if (!players[player] || !players[player]->entity) { return; } Stat* stats = entity->getStats(); if ( stats == NULL ) { return; } if ( player == 0 ) { shootmode = false; gui_mode = GUI_MODE_SHOP; shopInv = &stats->inventory; shopkeeper = entity->getUID(); shoptimer = ticks - 1; shopspeech = language[194 + rand() % 3]; shopinventorycategory = 7; sellitem = NULL; Entity* entity = uidToEntity(shopkeeper); shopkeepertype = entity->monsterStoreType; shopkeepername = stats->name; shopitemscroll = 0; identifygui_active = false; closeRemoveCurseGUI(); //Initialize shop gamepad code here. if ( shopinvitems[0] != nullptr ) { selectedShopSlot = 0; warpMouseToSelectedShopSlot(); } else { selectedShopSlot = -1; } } else if ( multiplayer == SERVER ) { // open shop on client Stat* entitystats = entity->getStats(); strcpy((char*)net_packet->data, "SHOP"); SDLNet_Write32((Uint32)entity->getUID(), &net_packet->data[4]); net_packet->data[8] = entity->monsterStoreType; strcpy((char*)(&net_packet->data[9]), entitystats->name); net_packet->data[9 + strlen(entitystats->name)] = 0; net_packet->address.host = net_clients[player - 1].host; net_packet->address.port = net_clients[player - 1].port; net_packet->len = 9 + strlen(entitystats->name) + 1; sendPacketSafe(net_sock, -1, net_packet, player - 1); // fill client's shop inventory with items node_t* node; for ( node = entitystats->inventory.first; node != NULL; node = node->next ) { Item* item = (Item*)node->element; strcpy((char*)net_packet->data, "SHPI"); SDLNet_Write32(item->type, &net_packet->data[4]); net_packet->data[8] = (char)item->status; net_packet->data[9] = (char)item->beatitude; net_packet->data[10] = (unsigned char)item->count; SDLNet_Write32((Uint32)item->appearance, &net_packet->data[11]); if ( item->identified ) { net_packet->data[15] = 1; } else { net_packet->data[15] = 0; } net_packet->address.host = net_clients[player - 1].host; net_packet->address.port = net_clients[player - 1].port; net_packet->len = 16; sendPacketSafe(net_sock, -1, net_packet, player - 1); } } entity->skill[0] = 4; // talk state entity->skill[1] = players[player]->entity->getUID(); messagePlayer(player, language[1122], stats->name); }
void sellItemToShop(Item* item) { if ( !item ) { return; } if ( item->beatitude < 0 && itemIsEquipped(item, clientnum) ) { messagePlayer(clientnum, language[1124], item->getName()); playSound(90, 64); return; } bool deal = true; if ( stats[clientnum]->PROFICIENCIES[PRO_TRADING] >= CAPSTONE_UNLOCK_LEVEL[PRO_TRADING] ) { //Skill capstone: Can sell anything to any shop. } else { switch ( shopkeepertype ) { case 0: // arms & armor if ( itemCategory(item) != WEAPON && itemCategory(item) != ARMOR && itemCategory(item) != THROWN ) { deal = false; } break; case 1: // hats if ( itemCategory(item) != ARMOR ) { deal = false; } break; case 2: // jewelry if ( itemCategory(item) != RING && itemCategory(item) != AMULET && itemCategory(item) != GEM ) { deal = false; } break; case 3: // bookstore if ( itemCategory(item) != SPELLBOOK && itemCategory(item) != SCROLL && itemCategory(item) != BOOK ) { deal = false; } break; case 4: // potion shop if ( itemCategory(item) != POTION ) { deal = false; } break; case 5: // magicstaffs if ( itemCategory(item) != MAGICSTAFF ) { deal = false; } break; case 6: // food if ( itemCategory(item) != FOOD ) { deal = false; } break; case 7: // tools case 8: // lights if ( itemCategory(item) != TOOL && itemCategory(item) != THROWN ) { deal = false; } break; default: break; } } if ( !deal ) { shopspeech = language[212 + rand() % 3]; shoptimer = ticks - 1; playSound(90, 64); return; } if ( items[item->type].value * .75 <= item->sellValue(clientnum) ) { shopspeech = language[209 + rand() % 3]; } else { shopspeech = language[206 + rand() % 3]; } shoptimer = ticks - 1; newItem(item->type, item->status, item->beatitude, 1, item->appearance, item->identified, shopInv); stats[clientnum]->GOLD += item->sellValue(clientnum); playSound(89, 64); int ocount = item->count; item->count = 1; messagePlayer(clientnum, language[1125], item->description(), item->sellValue(clientnum)); item->count = ocount; if ( multiplayer != CLIENT ) { if ( rand() % 2 ) { if ( item->sellValue(clientnum) <= 1 ) { // selling cheap items does not increase trading past basic if ( stats[clientnum]->PROFICIENCIES[PRO_TRADING] < SKILL_LEVEL_SKILLED ) { players[clientnum]->entity->increaseSkill(PRO_TRADING); } } else { players[clientnum]->entity->increaseSkill(PRO_TRADING); } } } else { strcpy((char*)net_packet->data, "SHPS"); SDLNet_Write32(shopkeeper, &net_packet->data[4]); // send item that was sold to server SDLNet_Write32(item->type, &net_packet->data[8]); SDLNet_Write32(item->status, &net_packet->data[12]); SDLNet_Write32(item->beatitude, &net_packet->data[16]); SDLNet_Write32((Uint32)item->appearance, &net_packet->data[20]); if ( item->identified ) { net_packet->data[24] = 1; } else { net_packet->data[24] = 0; } net_packet->data[25] = clientnum; net_packet->address.host = net_server.host; net_packet->address.port = net_server.port; net_packet->len = 26; sendPacketSafe(net_sock, -1, net_packet, 0); } consumeItem(item); sellitem = NULL; }
void buyItemFromShop(Item* item) { if ( !item ) { return; } if ( stats[clientnum]->GOLD >= item->buyValue(clientnum) ) { if ( items[item->type].value * 1.5 >= item->buyValue(clientnum) ) { shopspeech = language[200 + rand() % 3]; } else { shopspeech = language[197 + rand() % 3]; } shoptimer = ticks - 1; Item* itemToPickup = newItem(item->type, item->status, item->beatitude, 1, item->appearance, item->identified, nullptr); itemPickup(clientnum, itemToPickup); stats[clientnum]->GOLD -= item->buyValue(clientnum); playSound(89, 64); int ocount = item->count; item->count = 1; messagePlayer(clientnum, language[1123], item->description(), item->buyValue(clientnum)); item->count = ocount; if ( multiplayer != CLIENT ) { Entity* entity = uidToEntity(shopkeeper); if (entity) { Stat* shopstats = entity->getStats(); shopstats->GOLD += item->buyValue(clientnum); } if ( rand() % 2 ) { if ( item->buyValue(clientnum) <= 1 ) { // buying cheap items does not increase trading past basic if ( stats[clientnum]->PROFICIENCIES[PRO_TRADING] < SKILL_LEVEL_SKILLED ) { players[clientnum]->entity->increaseSkill(PRO_TRADING); } } else { players[clientnum]->entity->increaseSkill(PRO_TRADING); } } else if ( item->buyValue(clientnum) >= 150 ) { if ( item->buyValue(clientnum) >= 300 || rand() % 2 ) { players[clientnum]->entity->increaseSkill(PRO_TRADING); } } } else { strcpy((char*)net_packet->data, "SHPB"); SDLNet_Write32(shopkeeper, &net_packet->data[4]); // send item that was bought to server SDLNet_Write32(item->type, &net_packet->data[8]); SDLNet_Write32(item->status, &net_packet->data[12]); SDLNet_Write32(item->beatitude, &net_packet->data[16]); SDLNet_Write32((Uint32)item->appearance, &net_packet->data[20]); if ( item->identified ) { net_packet->data[24] = 1; } else { net_packet->data[24] = 0; } net_packet->data[25] = clientnum; net_packet->address.host = net_server.host; net_packet->address.port = net_server.port; net_packet->len = 26; sendPacketSafe(net_sock, -1, net_packet, 0); } consumeItem(item); } else { shopspeech = language[203 + rand() % 3]; shoptimer = ticks - 1; playSound(90, 64); } }
void actGoldBag(Entity *my) { int i; if( my->flags[INVISIBLE] ) { if( multiplayer!=CLIENT ) { node_t *node; for( node=map.entities->first; node!=NULL; node=node->next ) { Entity *entity = (Entity *)node->element; if( entity->sprite == 245 ) // boulder.vox return; } my->flags[INVISIBLE] = FALSE; serverUpdateEntityFlag(my,INVISIBLE); if( !strcmp(map.name,"Sokoban") ) { for( i=0; i<MAXPLAYERS; i++ ) steamAchievementClient(i,"BARONY_ACH_PUZZLE_MASTER"); } } else { return; } } GOLDBAG_AMBIENCE--; if( GOLDBAG_AMBIENCE<=0 ) { GOLDBAG_AMBIENCE = TICKS_PER_SECOND*30; playSoundEntityLocal( my, 149, 16 ); } // pick up gold if( multiplayer!=CLIENT ) { for(i=0;i<MAXPLAYERS;i++) { if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) { if(inrange[i]) { if (players[i] && players[i]->entity) playSoundEntity(players[i]->entity, 242+rand()%4, 64 ); stats[i]->GOLD += GOLDBAG_AMOUNT; if( i!=0 ) { if( multiplayer==SERVER ) { // send the client info on the gold it picked up strcpy((char *)net_packet->data,"GOLD"); SDLNet_Write32(stats[i]->GOLD,&net_packet->data[4]); net_packet->address.host = net_clients[i-1].host; net_packet->address.port = net_clients[i-1].port; net_packet->len = 8; sendPacketSafe(net_sock, -1, net_packet, i-1); } } // message for item pickup if( GOLDBAG_AMOUNT==1 ) messagePlayer(i,language[483]); else messagePlayer(i,language[484],GOLDBAG_AMOUNT); // remove gold entity list_RemoveNode(my->mynode); return; } } } } else { my->flags[NOUPDATE] = TRUE; } }
void actItem(Entity* my) { Item* item; int i; if ( multiplayer == CLIENT ) { my->flags[NOUPDATE] = true; if ( ITEM_LIFE == 0 ) { Entity* tempEntity = uidToEntity(clientplayer); if ( tempEntity ) { if ( entityInsideEntity(my, tempEntity) ) { my->parent = tempEntity->getUID(); } else { node_t* node; for ( node = map.creatures->first; node != nullptr; node = node->next ) { Entity* entity = (Entity*)node->element; if ( entity->behavior == &actPlayer || entity->behavior == &actMonster ) { if ( entityInsideEntity(my, entity) ) { my->parent = entity->getUID(); break; } } } } } else { node_t* node; for ( node = map.creatures->first; node != nullptr; node = node->next ) { Entity* entity = (Entity*)node->element; if ( entity->behavior == &actPlayer || entity->behavior == &actMonster ) { if ( entityInsideEntity(my, entity) ) { my->parent = entity->getUID(); break; } } } } } // request entity update (check if I've been deleted) if ( ticks % (TICKS_PER_SECOND * 5) == my->getUID() % (TICKS_PER_SECOND * 5) ) { strcpy((char*)net_packet->data, "ENTE"); net_packet->data[4] = clientnum; SDLNet_Write32(my->getUID(), &net_packet->data[5]); net_packet->address.host = net_server.host; net_packet->address.port = net_server.port; net_packet->len = 9; sendPacketSafe(net_sock, -1, net_packet, 0); } } else { // select appropriate model my->skill[2] = -5; if ( my->itemSokobanReward != 1 ) { my->flags[INVISIBLE] = false; } item = newItemFromEntity(my); my->sprite = itemModel(item); free(item); } //if( ITEM_LIFE==0 ) // playSoundEntityLocal( my, 149, 64 ); ITEM_LIFE++; /*ITEM_AMBIENCE++; if( ITEM_AMBIENCE>=TICKS_PER_SECOND*30 ) { ITEM_AMBIENCE=0; playSoundEntityLocal( my, 149, 64 ); }*/ // pick up item if (multiplayer != CLIENT) { if ( my->isInteractWithMonster() ) { Entity* monsterInteracting = uidToEntity(my->interactedByMonster); if ( monsterInteracting ) { if ( my->skill[10] >= 0 && my->skill[10] < NUMITEMS ) { if ( items[my->skill[10]].category == Category::FOOD && monsterInteracting->getMonsterTypeFromSprite() != SLIME ) { monsterInteracting->monsterConsumeFoodEntity(my, monsterInteracting->getStats()); } else { monsterInteracting->monsterAddNearbyItemToInventory(monsterInteracting->getStats(), 24, 9, my); } } my->clearMonsterInteract(); return; } my->clearMonsterInteract(); } for ( i = 0; i < MAXPLAYERS; i++) { if ((i == 0 && selectedEntity == my) || (client_selected[i] == my)) { if (inrange[i]) { if (players[i] != nullptr && players[i]->entity != nullptr) { playSoundEntity( players[i]->entity, 35 + rand() % 3, 64 ); } Item* item2 = newItemFromEntity(my); if ( players[i] && players[i]->entity ) { if ( my->itemStolen == 1 && item2 && (static_cast<Uint32>(item2->ownerUid) == players[i]->entity->getUID()) ) { steamAchievementClient(i, "BARONY_ACH_REPOSSESSION"); } } //messagePlayer(i, "old owner: %d", item2->ownerUid); if (item2) { item = itemPickup(i, item2); if (item) { if (i == 0) { free(item2); } int oldcount = item->count; item->count = 1; messagePlayer(i, language[504], item->description()); item->count = oldcount; if (i != 0) { free(item); } my->removeLightField(); list_RemoveNode(my->mynode); return; } } } } } } if ( my->itemNotMoving ) { switch ( my->sprite ) { case 610: case 611: case 612: case 613: my->spawnAmbientParticles(80, my->sprite - 4, 10 + rand() % 40, 1.0, false); if ( !my->light ) { my->light = lightSphereShadow(my->x / 16, my->y / 16, 3, 192); } break; default: break; } if ( multiplayer == CLIENT ) { // let the client process some more gravity and make sure it isn't stopping early at an awkward angle. if ( my->itemNotMovingClient == 1 ) { return; } } else { return; } } // gravity bool onground = false; if ( my->z < 7.5 - models[my->sprite]->sizey * .25 ) { // fall // chakram and shuriken lie flat, needs to use sprites for client if ( my->sprite == 567 || my->sprite == 569 ) { // todo: adjust falling rates for thrown items if need be ITEM_VELZ += 0.04; my->z += ITEM_VELZ; my->roll += 0.08; } else { ITEM_VELZ += 0.04; my->z += ITEM_VELZ; my->roll += 0.04; } } else { if ( my->x >= 0 && my->y >= 0 && my->x < map.width << 4 && my->y < map.height << 4 ) { if ( map.tiles[(int)(my->y / 16)*MAPLAYERS + (int)(my->x / 16)*MAPLAYERS * map.height] || (my->sprite >= 610 && my->sprite <= 613) ) { // land ITEM_VELZ *= -.7; if ( ITEM_VELZ > -.35 ) { // chakram and shuriken lie flat, needs to use sprites for client if ( my->sprite == 567 || my->sprite == 569 ) { my->roll = PI; my->pitch = 0; if ( my->sprite == 569 ) { my->z = 8.5 - models[my->sprite]->sizey * .25; } else { my->z = 8.75 - models[my->sprite]->sizey * .25; } } else { my->roll = PI / 2.0; my->z = 7.5 - models[my->sprite]->sizey * .25; } ITEM_VELZ = 0; onground = true; } else { onground = true; my->z = 7.5 - models[my->sprite]->sizey * .25 - .0001; } } else { // fall ITEM_VELZ += 0.04; my->z += ITEM_VELZ; my->roll += 0.04; } } else { // fall ITEM_VELZ += 0.04; my->z += ITEM_VELZ; my->roll += 0.04; } } // falling out of the map if ( my->z > 128 ) { if ( ITEM_TYPE == ARTIFACT_MACE && my->parent != 0 ) { steamAchievementEntity(uidToEntity(my->parent), "BARONY_ACH_STFU"); } list_RemoveNode(my->mynode); return; } // don't perform unneeded computations on items that have basically no velocity double groundheight; if ( my->sprite == 569 ) { groundheight = 8.5 - models[my->sprite]->sizey * .25; } else if ( my->sprite == 567 ) { groundheight = 8.75 - models[my->sprite]->sizey * .25; } else { groundheight = 7.5 - models[my->sprite]->sizey * .25; } if ( onground && my->z > groundheight - .0001 && my->z < groundheight + .0001 && fabs(ITEM_VELX) < 0.02 && fabs(ITEM_VELY) < 0.02 ) { my->itemNotMoving = 1; my->flags[UPDATENEEDED] = false; if ( multiplayer != CLIENT ) { serverUpdateEntitySkill(my, 18); //update itemNotMoving flag } else { my->itemNotMovingClient = 1; } return; } // horizontal motion if ( ITEM_NOCOLLISION ) { double newx = my->x + ITEM_VELX; double newy = my->y + ITEM_VELY; if ( !checkObstacle( newx, newy, my, NULL ) ) { my->x = newx; my->y = newy; my->yaw += sqrt( ITEM_VELX * ITEM_VELX + ITEM_VELY * ITEM_VELY ) * .05; } } else { double result = clipMove(&my->x, &my->y, ITEM_VELX, ITEM_VELY, my); my->yaw += result * .05; if ( result != sqrt( ITEM_VELX * ITEM_VELX + ITEM_VELY * ITEM_VELY ) ) { if ( !hit.side ) { ITEM_VELX *= -.5; ITEM_VELY *= -.5; } else if ( hit.side == HORIZONTAL ) { ITEM_VELX *= -.5; } else { ITEM_VELY *= -.5; } } } ITEM_VELX = ITEM_VELX * .925; ITEM_VELY = ITEM_VELY * .925; }
void clickDescription(int player, Entity *entity) { stat_t *stat; Item *item; Uint32 uidnum; if( entity==NULL ) { if( !(*inputPressed(impulses[IN_ATTACK])) || shootmode ) return; if( omousex<camera.winx || omousex>=camera.winx+camera.winw || omousey<camera.winy || omousey>=camera.winy+camera.winh ) return; if (openedChest[clientnum]) if (omousex > CHEST_INVENTORY_X && omousex < CHEST_INVENTORY_X + inventoryChest_bmp->w && omousey > CHEST_INVENTORY_Y && omousey < CHEST_INVENTORY_Y + inventoryChest_bmp->h) return; //Click falls inside the chest inventory GUI. if (identifygui_active) if (omousex > IDENTIFY_GUI_X && omousex < IDENTIFY_GUI_X + identifyGUI_img->w && omousey > IDENTIFY_GUI_Y && omousey < IDENTIFY_GUI_Y + identifyGUI_img->h) return; //Click falls inside the identify item gui. if (book_open) if (mouseInBounds(BOOK_GUI_X, BOOK_GUI_X + bookgui_img->w, BOOK_GUI_Y, BOOK_GUI_Y + bookgui_img->h)) return; //Click falls inside the book GUI. if (gui_mode == GUI_MODE_INVENTORY || gui_mode == GUI_MODE_SHOP) { if( gui_mode == GUI_MODE_INVENTORY ) if (mouseInBounds(RIGHTSIDEBAR_X, RIGHTSIDEBAR_X + rightsidebar_titlebar_img->w, RIGHTSIDEBAR_Y, RIGHTSIDEBAR_Y + rightsidebar_height)) return; //Click falls inside the right sidebar. //int x = std::max(character_bmp->w, xres/2-inventory_bmp->w/2); //if (mouseInBounds(x,x+inventory_bmp->w,0,inventory_bmp->h)) //return NULL; if( mouseInBounds(INVENTORY_STARTX,INVENTORY_STARTX+INVENTORY_SIZEX*INVENTORY_SLOTSIZE,INVENTORY_STARTY,INVENTORY_STARTY+INVENTORY_SIZEY*INVENTORY_SLOTSIZE) ) { // clicked in inventory return; } if( gui_mode == GUI_MODE_SHOP ) { int x1 = xres/2-SHOPWINDOW_SIZEX/2, x2 = xres/2+SHOPWINDOW_SIZEX/2; int y1 = yres/2-SHOPWINDOW_SIZEY/2, y2 = yres/2+SHOPWINDOW_SIZEY/2; if (mouseInBounds(x1,x2,y1,y2)) return; } } else if (gui_mode == GUI_MODE_MAGIC) { if (magic_GUI_state == 0) { //Right, now calculate the spell list's height (the same way it calculates it for itself). int height = spell_list_titlebar_bmp->h; int numspells = 0; node_t *node; for (node = spellList.first; node != NULL; node = node->next) { numspells++; } int maxSpellsOnscreen = camera.winh / spell_list_gui_slot_bmp->h; numspells = std::min(numspells, maxSpellsOnscreen); height += numspells * spell_list_gui_slot_bmp->h; int spelllist_y = camera.winy + ((camera.winh / 2) - (height / 2)) + magicspell_list_offset_x; if (mouseInBounds(MAGICSPELL_LIST_X, MAGICSPELL_LIST_X + spell_list_titlebar_bmp->w, spelllist_y, spelllist_y + height)) return; } } if (mouseInBounds(0,224,0,420)) // character sheet return; int x = xres/2-(status_bmp->w/2); if (mouseInBounds(x,x+status_bmp->w,yres-status_bmp->h-hotbar_img->h,yres)) return; *inputPressed(impulses[IN_ATTACK])=0; if( softwaremode ) { entity = clickmap[omousey+omousex*yres]; } else { GLubyte pixel[4]; glReadPixels(omousex,yres-omousey,1,1,GL_RGBA,GL_UNSIGNED_BYTE,(void *)pixel); uidnum = pixel[0] + (((Uint32)pixel[1])<<8) + (((Uint32)pixel[2])<<16) + (((Uint32)pixel[3])<<24); entity = uidToEntity(uidnum); } } if( entity != NULL ) { if( multiplayer != CLIENT ) { if( (stat=entity->getStats())==NULL ) { Entity *parent = uidToEntity(entity->parent); if( entity->behavior==&actPlayerLimb || entity->skill[2]==entity->parent ) { if( parent ) { if( parent->behavior==&actPlayer || parent->behavior==&actMonster ) { stat_t *stats = parent->getStats(); if( stats ) { if( strcmp(stats->name,"") ) { messagePlayer(player,language[253],language[90+stats->type],stats->name); } else { messagePlayer(player,language[254],language[90+stats->type]); } } } } } else if( entity->behavior==&actTorch ) { messagePlayer(player,language[255]); } else if( entity->behavior==&actDoor ) { messagePlayer(player,language[256]); } else if( entity->behavior==&actItem ) { item = newItem(static_cast<ItemType>(entity->skill[10]),static_cast<Status>(entity->skill[11]),entity->skill[12],entity->skill[13],entity->skill[14],FALSE,NULL); if (item) { messagePlayer(player,language[257],item->description()); free(item); } } else if( entity->behavior==&actGoldBag ) { if( entity->skill[0]==1 ) messagePlayer(player,language[258]); else messagePlayer(player,language[259],entity->skill[0]); } else if( entity->behavior==&actCampfire) { messagePlayer(player,language[260]); } else if( entity->behavior==&actFountain) { messagePlayer(player,language[262]); } else if( entity->behavior==&actSink) { messagePlayer(player,language[263]); } else if( entity->behavior==&actLadder) { messagePlayer(player,language[264]); } else if( entity->behavior==&actLadderUp) { messagePlayer(player,language[265]); } else if( entity->behavior==&actChest || entity->behavior==&actChestLid ) { messagePlayer(player,language[266]); } else if( entity->behavior==&actGate) { messagePlayer(player,language[267]); } else if( entity->behavior==&actSpearTrap) { messagePlayer(player,language[268]); } else if( entity->behavior==&actSwitch) { messagePlayer(player,language[269]); } else if( entity->behavior==&actBoulder ) { messagePlayer(player,language[270]); } else if( entity->behavior==&actHeadstone ) { messagePlayer(player,language[271]); } else if( entity->behavior==&actPortal || entity->behavior==&actWinningPortal ) { messagePlayer(player,language[272]); } else if( entity->behavior==&actFurniture ) { if( entity->skill[0] ) messagePlayer(player,language[273]); else messagePlayer(player,language[274]); } } else { if( !strcmp(stat->name,"") ) { messagePlayer(player,language[254],language[90+stat->type]); } else { messagePlayer(player,language[253],language[90+stat->type],stat->name); } } } else { // send spot command to server strcpy((char *)net_packet->data,"SPOT"); net_packet->data[4]=player; SDLNet_Write32((Uint32)entity->uid,&net_packet->data[5]); net_packet->address.host = net_server.host; net_packet->address.port = net_server.port; net_packet->len = 9; sendPacketSafe(net_sock, -1, net_packet, 0); } } }