(原创)
目前正在不断更新!
★ 一款超级有趣的大乱斗游戏,包含多种游戏模式,支持双人联机。
离线情况下也可以与多个(或一群)机器玩家进行疯狂的对战。
直接上图
使用C++ with EGE图形库编写
有一定数量的BUG,请谅解。
[ ↑双人离线的一张截图 ]
操作说明
A,W,S,D | 主玩家移动
1/2/3/4 | 主玩家选择武器或道具
J | 主玩家向面前方向攻击
Backspace退格 | 主玩家删除当前武器或道具(注意:装备是靠刷新更好的,不能删)
鼠标左键 | 向鼠标方向攻击(非常方便),将被识别成八个方向之一(双人离线为了平等不能使用)
↑←↓→ | 双人离线时玩家2的移动
小键盘1/2/3/4 | 双人离线时玩家2选择武器或道具
小键盘0 | 双人离线时玩家2向面前方向攻击(原先是5,但因为不太好操作于是改了)
小键盘减号 | 双人离线时玩家2删除当前武器或道具
F2 | 立即窗口截图,存入Screenshots文件夹中
Esc | 退出战斗
基本玩法
比如说人机离线对战模式(是可以使用鼠标攻击的),
开局就先随机获得两把武器,两个道具,没有装备。
你可以通过右侧的对方方位与距离锁定敌人的位置进行有效攻击。
机器玩家的算法还说得过去,有时真难弄死它。
[↑ 人机对战的一张截图 ]
普通模式下一般都是300滴血,只有比较容易死的模式会1000血甚至5000血。(自己探索)
有些武器带效果的,要注意防护与使用:
有些剑是带剑气的;
有些弹药是会反弹/爆炸/分裂/追踪(分为3种等级)/穿墙的。
武器千奇百怪,战斗场面琳琅满目:
[↑ 混战模式的一张截图 ——那个血量不是正常的血量,请忽视 ]
群殴模式是很难挺过去的,你可以尝试一下!!
群殴模式会给你1000血加上长时间的矫捷效果与永久的穿人特权。就算这样也能死得很惨。
诀窍是不断逃跑,让他们自己误伤。逃跑的时候注意安全。
- 离线团战一定要把对方所有人消灭,但自己死了就算失败了。
- 作为队伍头领,一定要学会保护自己!
- 队伍颜色是随机的
- 右侧将会有显示真实水平的击杀榜、队伍剩余人数、最近敌人等数据。
★ 新版本加了一个叫等级与经验的机制(如上图左上角),击杀、伤害敌人,拾取物资都会获取经验,经验达到一定水平后等级+1.等级的高低将决定所抽武器道具装甲的好坏!!(等级最高10级)
最后关于联机:
-
在线模式下服务端开启后,客户端依次输入服务端IP地址和端口号即可
(若无外网则必须同一局域网下)
配置外网时映射的IP需要是服务端开启后显示的IP(也就是服务端电脑第一个能用的IP),
-
端口号一律填8888.
使用外网时,在输入IP地址界面不得输入域名。
客户端输入的端口号是映射后的端口号(一般是五位数而不是8888)
需要使用IP地址。获取其IP地址可以通过ping命令获得:
Win+R打开运行,输入cmd
-
联机的时候经常会崩溃,应该是这个TCP连接太差劲的缘故,也么有办法,因此我尽量减少机器玩家的数量。凑合着玩吧。不要使用频率极高的武器,因为更容易致使崩溃。
这款游戏已经写了一年左右了,祝愿大家玩得愉快
源码真的很长(一万多行了!)真的想要的话(也不给 XD )
无源码的游戏链接: https://download.csdn.net/download/cjz2005/86287023
★★★
为了造福广大苍生,我决定放一点源码给大家看看!
这是机器玩家的AI算法,原创,还行,有兴趣的同志可以好好研究一下。
//Dir Modes
#define DIR_NONE 0x00
#define DIR_4 0x01
#define DIR_8 0x02//AI Modes
#define AAM_STILL 0 //静止
#define AAM_WANDER 1 //多逛
#define AAM_CHASE 2 //多追
#define AAM_FLEE 3 //多逃//Constants
#define AA_CHANGE_MODE_RATE 25 //模式更改机率
#define AA_CHANGE_MODE_MIN_T 1000*6 //模式更改最小周期
#define AA_CHANGE_WEAPON_RATE 32 //武器切换概率
#define AA_CHANGE_WEAPON_MIN_T 1000*8 //武器切换最小周期
#define AA_LEVEL_UP_T 1000*43 //等级提升周期
#define AA_DRINK_POTION_RATE 8 //喝药水概率
#define AA_DODGE_BASE_RATE 13 //基础闪避概率
#define AA_DODGE_RATE_MAX 60 //闪避概率最大值
#define AA_DODGE_UP_RATIO 0.5 //闪避提升率
#define AA_DODGE_T 1000*0.9 //闪避周期
#define AA_EXTRA_DODGE_RATE_T 1000*65 //闪避概率微调周期
#define AA_CHANGE_TARGET_MIN_T 11000 //目标切换最小周期
#define AA_CHANGE_TARGET_RATE 8 //目标切换概率
#define AA_REVENGE_RATE 40 //复仇概率class AIControl { //AI控制玩家算法
public:bool enabled; //是否启用 int my_index; //附着玩家下标 int target_index; //目标玩家下标(可变) int team_index; //队伍下标clock_t lastModeChanged; //上一次切换模式 clock_t lastWeaponChanged; //上一次切换武器 clock_t lastChangeTarget; //上一次切换攻击目标 clock_t lastUp; clock_t lastDodge; //上一次闪避 clock_t lastExtraRateChanged; //上一次改变额外躲闪率 int extraDodgeRate; //额外躲闪率 int mode; //AI模式 int xp; //经验值BYTE extraMode; //作弊额外模式 float adjust;const vector<int> mode_prob = { 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3 }; //带比重const vector<int> curw_prob = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3 }; //带比重AIControl(){target_index = 0; //默认主角为目标team_index = 0;adjust = 0;enabled = false;Init();}void Init() //initialize{my_index = 1; //<!>target_index = 0; //默认主角为目标extraDodgeRate = 0;extraMode = AAE_NONE;mode = AAM_CHASE;lastModeChanged = clock() + 5000;lastWeaponChanged = clock();lastExtraRateChanged = clock();lastChangeTarget = clock();lastUp = clock();lastDodge = clock();xp = 0;adjust = (GetPlayerCount() * 5 + 10101 + RandomRange(0, 100, true, false)) % 100 / 100.0;}void Close() //关闭 {enabled = false;mode = AAM_STILL;xp = 0;target_index = 0;}void Update() //更新{if (!enabled || !IsPlayerAlive(my_index)) //未启用状态或死亡状态直接退出 return;CheckLevelUp();int r;//离线模式下,玩家2成为AI玩家//在线模式下,自己成为AI玩家(自动攻击)r = RandomRange(0, 100, true, false); //percentif (r > 100 - AA_CHANGE_MODE_RATE - adjust*6 && (clock() - lastModeChanged > AA_CHANGE_MODE_MIN_T)){mode = mode_prob.at(RandomRange(0, mode_prob.size() - 1, true, true));lastModeChanged = clock();}if (clock() - lastExtraRateChanged > AA_EXTRA_DODGE_RATE_T){extraDodgeRate = Varience(0, 5+adjust*6);lastExtraRateChanged = clock();}Move(); //根据模式进行移动if (clock() - lastDodge > AA_DODGE_T + adjust * 3){TryToDodge(); //checking inside}if (g_bIdt != IDT_OFFLINE){if(GetDirMode(GetPlayerCurWeapon(my_index)) == DIR_8)GetPlayerFace(my_index) = FaceDir8(target_index);elseGetPlayerFace(my_index) = FaceDir4(target_index);}#ifndef AI_CONCENTRATEif(g_mode != 0 && g_mode != 1 && g_mode != 2 //就两个玩家时无需切换 && g_mode != 3 //离线群殴始终只有一个目标&& (!IsPlayerAlive(target_index) //目标死了就赶紧换目标 没有CD和概率要求|| (RandomRange(0,100,true,false) < AA_CHANGE_TARGET_RATE + adjust * 9 //还有概率 && clock() - lastChangeTarget >= AA_CHANGE_TARGET_MIN_T))){ //切换目标 int new_target_index = this->target_index;int min_dist = 9999;for(int i = 0; i < GetPlayerCount(); ++i){if (!IsPlayerAlive(i) || i == my_index)continue;if ((g_mode == 5 || g_mode == 9)&& GetPlayerTeam(i) == team_index){ //团战时 放过队友continue;}if ((g_mode == 6 || g_mode == 7) && i != 0 && i != 1)continue; //在线群殴只能以人为目标auto _dist = Distance(GetX(),GetY(),GetPlayerX(i),GetPlayerY(i));if(_dist < min_dist){new_target_index = i;min_dist = _dist;}}this->target_index = new_target_index;/*if(mode != AAM_CHASE && RandomRange(0,100,true,false) < AA_CHANGE_MODE_RATE + adjust * 8){ //追赶加强this->mode = AAM_CHASE;}*/}
#endifif (RandomRange(0, 100, true, false) < 20 + adjust * 10)this->mode = AAM_CHASE;Attack(); //根据模式进行攻击}void CheckLevelUp(){if (clock() - lastUp > AA_LEVEL_UP_T){int upv = 1; //升级默认1级if (GetPlayerHp(my_index) > 1 && GetPlayerHp(target_index) > GetPlayerHp(my_index) * 1.8)upv = 2; //当血量差得太远的时候,升级加速xp += upv; lastUp = clock();}}void OnHurt(int hurt_by) //受伤时调用{if(!enabled)return;lastUp += 1000 * RandomRange(0,3,true,true); //经验有增长的趋势if(mode == AAM_STILL || mode == AAM_WANDER) //迅速进入正常状态lastModeChanged += 1000 * 4 + adjust * 100;if (PlayerHasAffect(my_index,3) || PlayerHasAffect(my_index,7) || PlayerHasAffect(my_index,11) || PlayerHasAffect(my_index,12)){extraDodgeRate += RandomRange(5, 9 + adjust * 2, true, false); //躲闪率微调}else {extraDodgeRate += RandomRange(4, 7 + adjust * 2, true, false); //躲闪率微调}if (hurt_by != my_index && hurt_by != target_index //非我非你&& (g_mode == 5 || g_mode == 9) || (GetPlayerTeam(hurt_by) != team_index) //异队&& g_mode != 3 //<!>离线群殴没有复仇;在线群殴还是有复仇的){if (RandomRange(0, 100, true, false) < AA_REVENGE_RATE){ //复仇target_index = hurt_by;}}}DIR FaceDir8(int i) const{POINT et{GetPlayerX(i),GetPlayerY(i)};if (IsOuttaField(POINT2(et.x, et.y)))return 0;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index); int ey = GetPlayerY(target_index); if (x < ex){if (y > ey) return RIGHTUP;else if (y < ey) return RIGHTDOWN;else return RIGHT;}else if (x > ex){if (y > ey) return LEFTUP;else if (y < ey) return LEFTDOWN;else return LEFT;}else {if (y > ey) return UP;else return DOWN;}}DIR FaceDir4(int i) const{POINT et{GetPlayerX(i),GetPlayerY(i)};if (IsOuttaField(POINT2(et.x, et.y)))return 0;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index); int ey = GetPlayerY(target_index); if (ex > x){if (ey > y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? RIGHT : DOWN) : (RandomRange(1, 10) > 7 ? DOWN : RIGHT));else if (ey < y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? RIGHT : UP) : (RandomRange(1, 10) > 7 ? UP : RIGHT));elsereturn RIGHT;}else if (ex < x){if (ey > y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? LEFT : DOWN) : (RandomRange(1, 10) > 7 ? DOWN : LEFT));else if (ey < y)return (abs(ex - x) > abs(ey - y) ? (RandomRange(1, 10) > 7 ? LEFT : UP) : (RandomRange(1, 10) > 7 ? UP : LEFT));elsereturn LEFT;}else {if (ey > y)return DOWN;elsereturn UP;}}UINT GetI() const { //获取下标/*if (enabled == false)return 2; //无else if (g_bIdt == IDT_OFFLINE)return 1;elsereturn g_p_i;*/return my_index;}UINT GetOppoI() const {return target_index; }int GetX() const{return GetPlayerX(GetI());}int GetY() const{return GetPlayerY(GetI());}void _Tag(string text) const{setcolor(WHITE);setbkmode(OPAQUE);setfont(20, 0, "微软雅黑");xyprintf(20, 500, "TAG:%s", text.c_str());}void Move(){EXCEPTION_L//debug _Tag("Move");/*if (mode == AAM_STILL){return;}else */if (mode == AAM_WANDER){if (!PlayerTimeToMove(my_index))return;DIR dir;int x, y;_retry:dir = 2 * RandomRange(1, 4, true, true) - 1;x = GetX();y = GetY();if (PlayerHasAffect(GetI(), 12))dir = OppoDir(dir);DirOffsetPos(x, y, dir, "AIControl::Move");if (IsOuttaField(POINT2(x,y)) || IsBarrier(bk(x, y, "AIControl::Move"))){goto _retry;}//MoveGetPlayerX(my_index) = x;GetPlayerY(my_index) = y;bool sendMsg = (g_bIdt != IDT_OFFLINE);if (sendMsg)SendTCP(UM_SETPOS, x, y, GetI());
// p[GetI()].lastMove = clock();LastMove(my_index);}else if (mode == AAM_CHASE || mode == AAM_FLEE || mode == AAM_STILL){if (!PlayerTimeToMove(my_index))return;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index);int ey = GetPlayerY(target_index);DIR xd, yd;if (ex > x)xd = RIGHT;else if (ex < x)xd = LEFT;elsexd = 0;if (ey > y)yd = DOWN;else if (ey < y)yd = UP;elseyd = 0;int r = RandomRange(0, 1, true, true);DIR dir; //final dirif (xd == RIGHT){if (yd == 0)dir = RIGHT;else {dir = (r ? RIGHT : yd);}}else if (xd == LEFT){if (yd == 0)dir = LEFT;else {dir = (r ? LEFT : yd);}}else {dir = yd;}if (mode == AAM_FLEE) //相反逃离dir = OppoDir(dir);if (PlayerHasAffect(GetI(), 12))dir = OppoDir(dir); //混沌效果 直接再反//Move(CHASE)DirOffsetPos(x, y, dir,"AIControl::Move");if (!IsOuttaField(POINT2(x, y)) &&!IsBarrier(bk(x,y,"AIControl::Move")) && //!(x == ex && y == ey) && //不能与对方重叠!HasPlayerTouch(my_index,dir) //不能与别的玩家重叠) {if (mode != AAM_STILL){bool sendMsg = (g_bIdt != IDT_OFFLINE);GetPlayerX(my_index) = x;GetPlayerY(my_index) = y;if (sendMsg)SendTCP(UM_SETPOS, x, y, GetI());}GetPlayerFace(my_index) = dir;
// p[GetI()].lastMove = clock();LastMove(my_index);//return;}elseLastMove(my_index);}else {}EXCEPTION_R_TITLED("BOP AIControl::Move EXCEPTION")}DIR GetComingDir(const Entity& et) const{if (IsOuttaField(POINT2(et.x, et.y)))return 0;int x = GetX();int y = GetY();int ex = GetPlayerX(target_index);int ey = GetPlayerY(target_index);DIR eface = et.face;if (eface == RIGHT && y == ey && x > ex)return LEFT;else if (eface == LEFT && y == ey && x < ex)return RIGHT;else if (eface == DOWN && x == ex && y > ey)return UP;else if (eface == UP && x == ex && y < ey)return DOWN;else if (eface == LEFTDOWN && (x - ex < 0) && (x - ex) / float(y - ey) == -1.0f)return RIGHTUP;else if (eface == LEFTUP && (x - ex < 0) && (x - ex) / float(y - ey) == 1.0f)return RIGHTDOWN;else if (eface == RIGHTDOWN && (x - ex > 0) && (x - ex) / float(y - ey) == 1.0f)return LEFTUP;else if (eface == RIGHTUP && (x - ex > 0) && (x - ex) / float(y - ey) == -1.0f)return LEFTDOWN;elsereturn 0;}void TryToDodge(){ //尝试躲闪 if (entities.empty())return;int x = GetX();int y = GetY();int dp;int r;dp = Varience(AA_DODGE_BASE_RATE,4) //基础也在变动+ xp * AA_DODGE_UP_RATIO + adjust * 3+ extraDodgeRate;//各种效果对其的影响if (PlayerHasAffect(my_index, 6))dp -= 4;if (PlayerHasAffect(my_index, 7))dp -= 3;if (PlayerHasAffect(my_index, 9))dp -= 6;if (PlayerHasAffect(my_index, 11))dp -= 10;else if (PlayerHasAffect(my_index, 12))dp -= 9;if (PlayerHasAffect(my_index, 1))dp -= 2;if (PlayerHasAffect(my_index, 14))dp -= 8; //隐身的时候得削弱一下,否则太难玩了ClampA(dp, AA_DODGE_BASE_RATE-5, AA_DODGE_RATE_MAX); //限制if (PlayerHasAffect(my_index, 4)) //矫捷dp += 3 + adjust * 1;//debug _Tag(ToString(dp));for (int i = 0; i < entities.size(); i++){double dist = Distance(x, y, entities.at(i).x, entities.at(i).y);DIR aimdir=0;if (aimdir = GetComingDir(entities.at(i))){int dextra_rate = 0; //根据距离决定的 额外 补充/扣除 概率if (dist < 2.1f)dextra_rate = 4;else if (dist < 4.4f)dextra_rate = 0;else if (dist < 6.3f)dextra_rate = -4;else if (dist < 10.5f)dextra_rate = -8;else {dextra_rate = -16;}r = RandomRange(0, 100, true, false);if (r < dp + dextra_rate){Dodge(aimdir); //尽力闪避}//continue;break;}}//end of for}bool FaceBarrier(int _x, int _y, DIR face){int nx = _x, ny = _y;DirOffsetPos(nx, ny, face, "FaceBarrier");if (IsBarrier(bk(nx, ny, string(__func__))) || IsOuttaField(POINT2(nx, ny)))return true;return false;}bool Dodge(DIR aimdir){ //调用此函数时,必须尽力闪避if (aimdir == 0)return false;if (PlayerHasAffect(my_index, 2) || PlayerHasAffect(my_index, 10)) //不能动的效果一定要中止,否则会被视为作弊return false;const vector<DIR> _choices{1,3,5,7}; //四向vector<DIR> choices{};DIR oppdir = 0; //最终选择for (int i = 0; i < _choices.size(); i++){if (_choices.at(i) != aimdir && _choices.at(i) != OppoDir(aimdir)){choices.push_back(_choices.at(i));}else if (_choices.at(i) == OppoDir(aimdir)){oppdir = _choices.at(i);}}if (oppdir != 0){choices.push_back(oppdir); //最后选择}bool sendMsg = (g_bIdt != IDT_OFFLINE);for (int k = 0; k < choices.size(); k++){if (!HasPlayerTouch(GetI(),choices.at(k)) //不碰玩家&& !FaceBarrier(GetX(),GetY(),choices.at(k)) //不碰壁,不出图){int x = GetX(), y = GetY();DirOffsetPos(x, y, choices.at(k), "Dodge");SetPlayerPos(GetI(), x, y); //闪避if (sendMsg)SendTCP(UM_SETPOS, x, y, GetI());return true; //成功}}return false; //闪避失败}
#define AA_CANREACH_RANGE_MAX 30bool CanReach(int x, int y, DIR face, int ex, int ey) const{ //能否打得到if (face == 0)return false;int _x = x, _y = y;int i = 0;if (face == RIGHT || face == LEFT){if (y != ey)return false;while (!IsOuttaField(POINT2(_x, _y)) && !IsBarrier(bk(_x, _y, "AIControl::CanReach")) && i < AA_CANREACH_RANGE_MAX){if (_x == ex && _y == ey)return true;DirOffsetPos(_x, _y, face, "AIControl::CanReach");i++;//DebugLog(ToString(i),false);}return false;}else if (face == DOWN || face == UP){if (x != ex)return false;while (!IsOuttaField(POINT2(_x, _y)) && !IsBarrier(bk(_x, _y, "AIControl::CanReach")) && i < AA_CANREACH_RANGE_MAX){if (_x == ex && _y == ey)return true;DirOffsetPos(_x, _y, face, "AIControl::CanReach");i++;//DebugLog(ToString(i), false);}return false;}else {if (x == ex || y == ey)return false;while (!IsOuttaField(POINT2(_x, _y)) && !IsBarrier(bk(_x, _y, "AIControl::CanReach")) && i < AA_CANREACH_RANGE_MAX){if (_x == ex && _y == ey)return true;DirOffsetPos(_x, _y, face, "AIControl::CanReach");i++;//DebugLog(ToString(i), false);}return false;}}double GetTargetDistance() const{ //获取目标距离 return Distance(GetPlayerX(my_index),GetPlayerY(my_index),GetPlayerX(target_index),GetPlayerY(target_index));}void Attack(){EXCEPTION_L//_Tag("Attack");int r = RandomRange(0, 100, true, false);if (r > 100 - AA_CHANGE_WEAPON_RATE && (clock() - lastWeaponChanged) > AA_CHANGE_WEAPON_MIN_T){do {GetPlayerCurWeaponIndex(my_index) = curw_prob.at(RandomRange(0, curw_prob.size() - 1, true, true));} while (GetPlayerCurWeaponIndex(my_index) == 0); //不能选空的格子lastWeaponChanged = clock();}
// double distance = GetOppoDistance();double distance = GetTargetDistance();UINT type = GetItemType(GetPlayerCurWeapon(my_index));int x = GetX();int y = GetY();int ex = GetPlayerX(target_index);int ey = GetPlayerY(target_index);DIR face = GetPlayerFace(my_index);UINT ptype;ITEM_ID id = GetPlayerCurWeapon(my_index);if(type == ITT_PROP)ptype = GetItemPropType(GetPlayerCurWeapon(my_index));if (type == ITT_BOW || type == ITT_GUN|| (type == ITT_PROP && ptype == ITPT_THROWABLE)) //远程武器{bool reach = CanReach(x, y, face, ex, ey);r = RandomRange(0, 100, true, false);int blind_prob = 10;if (mode == AAM_FLEE)blind_prob = 2;else if (type == ITT_PROP && ptype == ITPT_THROWABLE)blind_prob = 1;elseblind_prob = 11;if(reach && r > (mode == AAM_CHASE ? 49 : 62) || r < blind_prob)
// p[GetI()].TryToAttack(GetI(), (g_bIdt != IDT_OFFLINE)); //checking is insidePlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE)); //checking is inside}else if (type == ITT_CLOSE_WEAPON) //近战武器{ bool reach = distance < 3.3;r = RandomRange(0, 100, true, false);if(reach && r > (mode == AAM_CHASE ? 43 : 45) || r > (mode == AAM_FLEE ? 86 : 97))PlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE)); //checking is inside}else if (type == ITT_PROP) //道具{if (ptype == ITPT_PUT) //放置类{if (id == 33) //地雷{int prob = 5;if (distance < 6.0){if (mode == AAM_FLEE){ //逃亡中布地雷对方很容易中招prob = 40;}else if (mode == AAM_CHASE){ //追的时候就不一定了prob = 12;}else if (mode == AAM_STILL){ //判断对手是否朝自己方向来bool come = false;int delta_x, delta_y;DIR eface = GetPlayerFace(target_index);delta_x = ex - x;delta_y = ey - y;if (delta_x > 0 && eface == LEFT|| delta_x < 0 && eface == RIGHT|| delta_y > 0 && eface == UP|| delta_y < 0 && eface == DOWN)come = true;prob = (come?76:33);}}else {prob = 11;}r = RandomRange(0, 100, true, false);if (r < prob){ //布地雷PlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE)); //checking is inside}}else {//<!>other PUTs...}}else if (ptype == ITPT_POTION) //药水类,好的药水{r = RandomRange(0, 100, true, false);float t = AA_DRINK_POTION_RATE; //概率if (id >= 71 && id <= 73){if (GetPlayerHp(my_index) < GetPlayerMaxHp(my_index) * 0.10)t *= 5.0;else if (GetPlayerHp(my_index) < GetPlayerMaxHp(my_index) * 0.25)t *= 3.0;else if (GetPlayerHp(my_index) < GetPlayerMaxHp(my_index) * 0.45)t *= 1.6;}if (r < t){ //喝药水
// p[GetI()].TryToAttack(GetI(), (g_bIdt != IDT_OFFLINE));PlayerTryToAttack(my_index, (g_bIdt != IDT_OFFLINE));}}else {//other ITPTs...}}else {return;}EXCEPTION_R_TITLED("BOP AIControl::Attack EXCEPTION")}
};
//AIControl g_aic;
AIControl& GetPlayerAI(int index);
大致就包括自动移动、攻击、躲闪、喝药、埋地雷等,特别是那个躲闪很有意思,经验值越高躲闪越容易成功。
以后打算搞个游击模式算法。。等更新吧
下载: https://download.csdn.net/download/cjz2005/86287023